算法 - 二分法查找

什么是二分法查找

二分法查找主要是为了快速查找给定数组内,期待值在数组中的位置(下标)

二分法查找通过对整个数组取中间值,判断期待值所在的范围并缩小范围,每次查找范围折半,直到范围的边界重合,得出期待值的位置,如果找不到返回null

二分法有一个先决条件是:数组内元素必须是有序的

简单图解

给定一个包含1,3,5,7,8,9这一个元素的有序数组,求得期待值7所在的位置,下边用绿块表示指针所在位置

若是按照直接遍历的方式,绿块会从数组的第一个下标开始比较,直到7所在的下标得到结果,遍历需要4次,下边演示下二分法的图示

第一次,取值范围为整个数组,取数组长度中间值(0+5)/2取整2作为下标

取中间值初始以数组的第一个下标与最后一个下标相加取中间值,如果不为整,舍去小数部分

比较期待值与下标为2的值大小,发现5<7,7这个值应在中间值的右侧

缩小查找范围为中间值+1与最大下标

第二次,范围缩小为原数组的一半,下标不变,取中间值(3+5)/2=4

下标4对应的值8,大于7,所以向左取范围最小下标3,最大下标4-1=3

第三次,取中间值(3+3)/2=3,下标3上的值恰好与期待值相等,返回下标3

虽然看起来只少了一次,原因在数组的长度小,另外就是期待值设置的小,

再举个长一点的例子,这里有1-100的数组,100个元素,期待值为100

简单遍历次数最大为元素的个数n次,本例中100次

使用二分查找只需要log2n次,本例中17次!

二分法查找的Java实现

package binarysearch;

/**
 * 二分查找:求得期待值在有序数组中的位置
 * @author hellxz
 */
public class MyBinarySearch {

    /**
     * 二分查找算法实现
     * @param orderedArray 有序数组
     * @param expect 期待数值
     * @return 期待值在数组中的下标,如果期待数值不在数组中,返回null
     */
    public static Integer binarySearch(int[] orderedArray, int expect) {
        //low与high构成动态的数组下标范围
        //初始low下标为0,high为数组长度-1
        int low = 0;
        int high = orderedArray.length - 1;

        //当数组范围存在时,有两种情况:最小边界值小于最大边界值 或 两个边界值相等;
        //最小边界值不大于最大边界值是有意义的,表示范围的存在,如果范围不存在了,说明数组中无此元素
        while (low <= high) {
            //取两个边界下标的中间下标与中间值,作为下标时会自动取整
            int middle = (low + high) / 2;
            int middleVal = orderedArray[middle];
            //中间值与期待值相等,说明中间值的下标就是我们要找的期待数的下标
            if (middleVal == expect) {
                return middle;
            }
            //中间值小于期待值,我们需要将最小边界下标移到中间下标的下一位
            //此时,最大边界不变,最小边界变大,范围缩小原来一半
            if (middleVal < expect) {
                low = middle + 1;
            }
            //中间值大于期待值,说明最大边界应小于中间下标
            if (middleVal > expect) {
                high = middle - 1;
            }
        }

        //循环结束未返回下标说明数组中不存在期待元素,返回null
        return null;
    }

    public static void main(String[] args) {
        int[] arr = { 2, 4, 5, 6, 10, 18, 19,22, 25, 70};
        int expectVal = 25;
        System.out.printf("当前期待的值为%d,其所在的下标为%d", expectVal, binarySearch(arr, expectVal));
    }
}

最后

本人不是科班出身,很多知识都在学习中,算法与数据结构系列将不定时更新(学会哪个更哪个??)

原文地址:https://www.cnblogs.com/hellxz/p/11749937.html

时间: 2024-10-10 20:06:45

算法 - 二分法查找的相关文章

Java常用排序算法+程序员必须掌握的8大排序算法+二分法查找法

Java 常用排序算法/程序员必须掌握的 8大排序算法 本文由网络资料整理转载而来,如有问题,欢迎指正! 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排序(直接选择排序.堆排序) 4)归并排序 5)分配排序(基数排序) 所需辅助空间最多:归并排序 所需辅助空间最少:堆排序 平均速度最快:快速排序 不稳定:快速排序,希尔排序,堆排序. 先来看看 8种排序之间的关系: 1.直接插入排序 (1)基本思想:在要排序的一组数中,假设前面(n-1)[n>=2]

C语言的算法--------二分法查找

int find(int n,int a[],int l){int low=0;int high=l-1;int middle=0;while(low<high){middle=(low+high)>>1;if(n==a[middle]){printf("%d,%d",n,middle);return 1; }else if(n>a[middle])low=middle+1; elsehigh=middle-1; } return 0; } int main()

python的算法:二分法查找(1)

1.什么是二分法查找: 1.从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束: 2.如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较. 3.如果在某一步骤数组为空,则代表找不到. 每次都是i减半查找,其时间消耗为O(logn) 最简单的一个循环算法就是: def binary_search_loop(lst,value): low,high=0,len(value)-1 while low<=high: mid=

Java中的二分法查找算法

[ 什么是二分查找 ]  二分查找又称为折半查找,该算法的思想是将数列按序排列,采用跳跃式方法进行查找,即先以有序数列的中点位置为比较对象, 如果要找的元素值小于该中点元素,则将待查序列缩小为左半部分,否则为右半部分.以此类推不断缩小搜索范围. [ 二分查找的条件 ] 二分查找的先决条件是查找的数列必须是有序的. [ 二分查找的优缺点 ] 优点:比较次数少,查找速度快,平均性能好: 缺点:要求待查数列为有序,且插入删除困难: 适用场景:不经常变动而查找频繁的有序列表. [ 算法步骤描述 ] ①

I学霸官方免费教程二十九:Java查找算法之二分法查找

二分法查找算法 基本步骤:    第一步:获取数组中间的下标    第二步:中间下标处的值和目标值比较,如果目标值大,说明要找的值在数组的后边一半中    第三步:再次获取数组右边一半的中间下标    第四步:再次用获得的中间下标和目标值进行比较    后续步骤以此类推,这样每次查找都在"半份"数据中进行,所以又叫折半查找.这也是为什么使用二分法查找之前必须要对数组进行排序的原因.如果不排序,将无法判断目标值在哪"半份"中 实例: package algorithm

iOS 排序算法总结、二分法查找

还有一个:二分插入排序  平均时间O(n2)   稳定 1.插入排序 在要排序的一组数中,假设前面(n-1) [n>=2] 个数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的.如此反复循环,直到全部排好顺序. 直接插入排序是稳定的.算法时间复杂度O(n2)--[n的平方] main() { int  a[10],j,i,m; for(j=1;j<10;j++) { m=a[j]; for(i=j-1;i>=0;i--) { if(a[i]<m) b

顺序表的冒泡排序算法及二分法查找代码实现

本文主要实现了比较经典的冒泡排序算法(对已经有序或者基本有序的顺序表复杂度大大降低),和二分法查找,各位看官看代码吧 //冒泡排序算法及二分法查找 #include "stdio.h" typedef struct { int key; }SSTable_Elem_Type; typedef struct { SSTable_Elem_Type*elem; int length; }SSTable_Typedef; void Bubble_Sort(SSTable_Typedef*ST

stl_algorithm算法之二分法查找

二分法查找: 7.60.template <class ForwardIterator, class T> ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val) { ForwardIterator it; iterator_traits < ForwardIterator>::difference_type count, step; count = di

冒泡算法和二分法查找

1.对一个整形数组进行冒泡排序 public  static void mp(int []a){ for(int i=0;i<a.length;i++){ for(int j=i+1;j<a.length;j++){ if(a[i]<a[j]){ temp = a[i]; a[i] = a[j]; a[j] = temp; } } } } 2.二分法查找(针对已排序数组) public static int ef(int []a, int tag){ int low = 0; int h