二分查找的递归和非递归写法

Posted 隔壁王叔叔呀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分查找的递归和非递归写法相关的知识,希望对你有一定的参考价值。

大家都知道,二分查找算法是一种非常高效的算法(时间复杂度为logn),虽然二分查找算法很简单,但是也有很多容易出错的点,不知道你有没有听说过“十个二分九个错”,想要写出一个没有bug的二分还是不容易的,第一个二分查找出现在1946年,但是第一个没有bug的二分查找直到1962年才出现。今天我总结了二分法的递归算法和非递归算法

非递归算法

  • 核心代码如下:

public static int search(int a[],int n,int v){
        int left = 0;
        int right = n-1;
        int mid;
        while (left <= right){
            mid = (left + right) / 2;
            if (a[mid] == v) return mid;
            if (a[mid] < v){
                left = mid +1;
            }else if (a[mid] > v){
                right = mid -1;
            }
        }
        return -1;
    }

这里有三个容易出问题的点

  1. 循环退出的条件是left <= right,而非left < right。比如1,2,3找1,如果是left < right的话,先找到2,往左边找,再找到1,此时left == right,不会进入循环,出错

  2. mid = (left + right) / 2这种写法实际上是有问题的,如果left和right较大有可能会溢出,正确的写法是mid = left + (right - left) / 2.这里除以2可以用移位操作来替代,因为移位操作比除法速度快。

  3. left和right的更新,这里更新时要等于mid-1而不是mid,height要等于mid+1而不是mid。比如当left = right = 3时,如果不等于value,如果写错这里就会发生死循环。

递归写法

  • 核心代码:

public static int search(int a[],int v,int left,int right){
        if (left > right) return -1;
        int mid = left + ((right - left) >> 1);
        if (a[mid] == v){
            return mid;
        }else if(a[mid] > v){
            return search(a, v, leftmid-1);
        }else if (a[mid] < v){
            return search(a, v, mid+1right);
        }
        return -1;
    }


以上是关于二分查找的递归和非递归写法的主要内容,如果未能解决你的问题,请参考以下文章

递归和非递归的二分查找

2019.9.25-二分查找代码(递归和非递归方法)

二分查找(递归和非递归)

图解二分查找的递归和非递归实现

二分查找的递归和非递归实现

二分查找--递归和非递归(c++)考研自用