目录
前言
在介绍二分法之前我们先来做一个游戏
请你想一个0-100范围内的整数,然后我在七次之内猜出来你想的数是哪个数。我每猜一个数,你只需要告诉我是大了还是小了。
我为什么能最多七次就能猜出来呢?(带着疑问,看完这篇文章你就明白了)
什么是二分查找
通俗来说也就是折半查找,每次都排除一半的元素,在一次一次二分后找到目标元素。
注意:二分查找只能对有序的列表进行查找(列如按大小顺序排列的表)
具体步骤:
- 取中间元素,判断目标元素是比中间元素大还是小。如果相等直接查找成功,返回中间值。
- 如果目标元素小于中间元素,则说明目标是在整张表的左半部分,缩小表的右边界。
- 如果目标元素大于中间元素,则说明目标是在整张表的右半部分,增大表的左边界。
区间问题
注意:
在实现以上步骤的过程中,要注意区间问题,这也是二分法的易错点。其中“左闭右闭”和“左闭右开”这两种情况较为常见。当然你学会了以上两种,遇到“左开右闭”等不常见的情况你也能嘎嘎乱杀。
什么是“左闭右闭” “左闭右开”?
二到底是 while(left < right) 还是 while(left <= right),到底是right = middle呢,还是要right = middle - 1呢?
该如何应对?
看完以下内容你就知道了
int BinarySearch(SqList L,int target){
int right=L.length-1;//右区间为闭区间
int left=0;//左区间为闭区间
int mid;
while(left<=right){
mid=(left+right)/2;//找出中间值
if(L.data[mid]==target) //中间值正好就是要找的目标值
return mid;
else
if(L.data[mid]>target)//中间值大于目标值,说明目标值在左半部分
right=mid-1;//修改右值,将范围改为表的左半部分
else
left=mid+1;
}
}
以上代码为左闭右闭,即[left,right]
int BinarySearch(SqList L,int target){
int right=L.length;//右区间为开区间
int left=0;//左区间为闭区间
int mid;
while(left<right){//注意在右边为开区间时这里不取等
mid=(left+right)/2;//找出中间值
if(L.data[mid]==target) //中间值正好就是要找的目标值
return mid;
else
if(L.data[mid]>target)//中间值大于目标值,说明目标值在左半部分
right=mid;//修改右值,将范围改为表的左半部分.注意在右边为开区间时这里不用减一
else
left=mid+1;
时间复杂度
因为每次查找都是取一半,所以为查找次数最多为为
时间复杂度:O()