二分查找的递归和非递归写法
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;
}
这里有三个容易出问题的点
循环退出的条件是left <= right,而非left < right。比如1,2,3找1,如果是left < right的话,先找到2,往左边找,再找到1,此时left == right,不会进入循环,出错
mid = (left + right) / 2这种写法实际上是有问题的,如果left和right较大有可能会溢出,正确的写法是mid = left + (right - left) / 2.这里除以2可以用移位操作来替代,因为移位操作比除法速度快。
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, left, mid-1);
}else if (a[mid] < v){
return search(a, v, mid+1, right);
}
return -1;
}
以上是关于二分查找的递归和非递归写法的主要内容,如果未能解决你的问题,请参考以下文章