前言:
首先,我个人认为二分查找是一种很好用的查找方式,其有时也被称作折半查找。这个查找方法虽然简单,但是刚接触程序语言的好兄弟,可能也会有点懵。最近,刚好遇到了这样的题,正好就说说二分查找吧。
关于二分查找的解释以及个人理解:
其实二分查找,和我们数学上的二分法很像。查找的时候每次都是从数据的中间开始,按照一定规则向左或者向右继续查找。也因此,二分查找的数据被要求具有一定的规则。一般是有序性。也就是说,二分查找的数据一般是从大到小排序,或者从小到大排序。当然,也不排除在一定逻辑顺序的情况下,进行二分查找。这就要求程序员,在使用此方法之前要弄明白,要查找的数据具有什么样的顺序,以及按照这样的顺序,使用二分查找能不能达成自己的目的。
以一组数据为例。若我们要查找1 2 5 8 11 13中8的位置。
首先我们会进行中间位置的确定,由于我们的数组一般是从0开始的,那么下界设置为0好了,用l=0表示。也就是说,将上面的数据存入数组,1所在的位置为0。那么上界就是5,也就是数组中13的位置。我们用r=5表示。下面我将给出查找的过程:
第一次查找:mid=(l+r)/2; 此时算得mid=2。我们需明白,在计算机中除法运算,浮点数转整型值时,一般默认向下取整。而5<8.所以我们向右查找。将下界更新l=mid+1;即l=3;
第二次查找mid=(3+5)/2=4,而11>8。所以我们将上界更新,即r=mid-1;即r=3
第三次查找mid=(3+3)/2=3。刚好是8的位置。至此我们找到了8的位置
上面就是二分查找的一般实现过程,也不复杂。但是仔细一想,每次查找,其实都为我们减少了一半待查找的数据量。这样,即使最坏查找情况出现,我们的查找效率也比一般的遍历高很多倍。若数据不具备一定的顺序,可以根据需要进行排序。前提是要保证,排序后,所获得的数据是有用的。
关于二分查找折半转移时的注意事项:
想必,读者已经注意到。我在上面进行过程推导时,上下界变更时,存在加减1的情况。由于我们mid处的数据已经比较过,所以它的实际意义已经到头了。我们没必要再将其划入我们的查找范围,节省工作量。
还有如此设计,其实也便于我们的进行循环结束。由于每次转移时,存在加减一的情况。当l与r想邻时,必然会先会使l==r,然后产生交错。大家不妨仔细思考一下。以此我们可以设计循环的结束条件为l<=r为true。若为false,则结束循环。
关于二分查找无法找到目标值时的状况:
正如上文所说,当无法找到目标值时。二分查找就会产生l与r的交错。结束循环。我们只需要要判断,是否有位置信息传出,就能判断明白目标值是否在数据中。这个也可以用于数据查找。
关于二分查找的代码实现:
//二分查找,mnm[]为数据存储的数组
int l=0,r=tot-1;//此处tot-1为上界
while(l<=r){
int mid=(l+r)/2;
if(target==mnm[mid]){
tp=mid;
break;
}
else if(target>mnm[mid]){
l=mid+1;
}//向右
else if(target<mnm[mid]){
r=mid-1;
}//向左
}