二分搜索算法常见使用误区

2019独角兽企业重金招聘Python工程师标准>>> hot3.png


  • 直接使用二分搜索法,搜索一个无序的数组或集合。

    如果你运气好的话,可能会搜索到你想要的数据,但是大部分情况下你不能得到你想要的结果。因为二分搜索是按照中间值来计算你要搜索数据的范围,每次逐渐缩小范围。如果你的结果不在一个按照升序排列的数组中,你要搜索的数据很可能被遗弃,然后返回负值。我们可以通过如下所示一段程序来断言,数组是否是有序的。

for(int i=0; i< arr.length; i++) {
    if(arr[i]>arr[i+1]) {
        return 0
    }
    return 1;
}

  • 自己写了一个二分搜索算法,陷入了一个死循环,不知道为什么?

因为你的边界没有完全控制好,所以造成了这种情况。如下:

反面教材 1: 数组 int arr[] = {12,14,143,145,643,23453,233452}; 搜索数据 233452(直接陷入死循环)

int start = 0;
int end = arr.length-1;
while(start <= end) {
    int mid = (start + end) / 2;
    if(key < arr[mid]){
        end = mid;
    }else if(key > arr[mid]) {
        start = mid;
    }else {
        return mid;
    }
}
return -1;

如上这种写法看起貌似是正确的,如果仔细分析的话,会发现数组的长度为7

  • 第一次循环中间量mid=3

  • 第二次循环中间量mid=4

  • 第三次循环中间量mid=5

  • 第四次循环中间量mid=6

  • 第五次循环中间量mid=6

  • 第六次循环中间量mid=6

  • 第七次循环中间量mid=6

  • .....

  • 由此陷入死循环

反面教材 2: 如果我们通过调试之后,把程序调整成如下,循环搜索结果,发现依然是个死循环。最终卡在了中间值5上,究其原因是因为,我们的中间值不能一直缩小,所以最终导致这个问题。

int start = 0;
int end = arr.length-1;
while(start <= end) {
    int mid = (start + end) / 2;
    if(key < arr[mid]){
        end = mid + 1;
    }else if(key > arr[mid]) {
        start = mid - 1;
    }else {
        return mid;
    }
}
return -1;

正确写法如下:(迭代过程中,循环不断减小。)

int start = 0;
int end = arr.length-1;
while(start <= end) {
    int mid = (start + end) / 2;
    if(key < arr[mid]){
        end = mid - 1;
    }else if(key > arr[mid]) {
        start = mid + 1;
    }else {
        return mid;
    }
}
return -1;

如果一个有序数组中,存在相同的数字,我们怎么保证返回所有的呢?

转载于:https://my.oschina.net/u/1787735/blog/862061

你可能感兴趣的:(二分搜索算法常见使用误区)