对分查找

对分查找要求顺序结构存储

int main()
{
    int i;
    int n = 5;
    int arr[30] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30};
    i = binarySearch(arr,30,n);
    printf("%d",i);
}

int binarySearch(int arr[],int len,int num)
{
    int first,middle,last;
    first = 0; 
    last = len - 1; 
    while(first <= last){
        middle = (first + last) ;
        if(arr[middle] < num){
            //如果arr[middle] < num,那么arr[middle] = num的位置必定在middle的前面,所以头部可以直接从middle+1开始
            first = middle + 1;
        }else if(arr[middle] > num){
            //如果arr[middle] > num,那么arr[middle] = num的位置必定在middle的后面,所以尾部必定不会超过middle-1
            last = middle - 1;
        }else{
            return middle;
        }
    }
    return -1;
}
middle = (first + last) / 2;

我每一次都是取arr数组中间的一个数与我要寻找的n(n是我需要寻找的数)作对比,如果arr[middle] < n那么arr[middle]前面的所有数都不是n,所有我们可以直接将数组的头部变成middle + 1
对分查找_第1张图片我们可以看这个数轴,middle < n,那么n是在middle到last之间,那我们直接舍弃first-middle

对分查找_第2张图片我们将数轴1变成数轴2,这样反复的循环直到找到n的位置

在代码中我使用了first <= last作为循环条件,这个条件刚开始时我也很懵懂,我们一步一步的推导也就可以得到答案了

假如n不在此数轴当中并且比数轴最大值还要大。数轴2中first的下标为14,last的下标为29
middle =(14+29)/ 2 = 21,此时middle还是小于n
那我们继续查找,first = middle + 1 = 21 + 1 = 22,last还是29不变,middle再次变化为(22+29)/ 2 = 25,middle小于n,再继续找,first = middle + 1 = 25 + 1 = 26,middle = (26+29) / 2 =27,middle < n
再继续找找到n为止或找到数轴的顶/尾端,first = middle + 1 = 27 + 1 = 28,middle = (28 + 29) / 2 = 28,middle < n
first = middle + 1 = 28 + 1 =29,middle = (29+29) / 2 = 29,middle < n
first = middle + 1 = 29 + 1 = 30

29是我们数组最后一个下标,也就代表我们我们找完了,如果下标29不是我们需要寻找的数,那我们也就可以结束了。
得出条件就是first <= last

如有错误请指出

你可能感兴趣的:(C)