经典算法04 折半查找
活动地址:CSDN21天学习挑战赛
*学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。
算法思想
折半查找又称“二分查找”,仅适用于有序的顺序表(即要么递增,要么递减 的数组)
查找成功:
在数组中,查找33这个元素(图片来自王道考研)
首先,使用两个指针,low和high分别指向所要搜索数组的区间范围,low指向第一个,high指向最后一个元素(图片来自王道考研)
第一轮,我我们需要检查low和high中间的元素,即mid,而mid=(low+high)/2
mid指向29,要小于33,即如果33存在,那么33一定在mid右边
将low指向29右边一个元素,即指向32,检查low和high中间元素
重复上面操作,mid指向中间37,37大于33,故33存在只能在37左边,所以high指针指向37左边 (图片来自王道考研)
重复上面操作,mid=6,此时32小于33,low指向32右边,low与high重合,检查7号元素,为33,查找成功(图片来自王道考研)
查找失败:
在数组中查找12(图片来自王道考研)
重复上述方法, high=19(图片来自王道考研)
再次重复,mid=13(图片来自王道考研)
经比较,low=10要小于12,low指针向右移,此时low大于high,即查找失败(图片来自王道考研)
代码实现:
//折半查找
int Binary_Search (SSTable L, ElemType key){
int low=0, high=L.TableLen-1, mid;
while( low<=high) {
mid=(low+high) /2; //取中间位置
if(L.elem[mid]==key)
return mid; //查找成功则返回所在位置
else if(L.elem[mid]>key)
high=mid-1; //从前半部分继续查找
else
low=mid+1; //从后半部分继续查找
}
return -1; //查找失败,返回-1
}
typedef struct{ //查找表的数据结构(顺序表)
ElemType *elem; //动态数组基址
int TableLen; //表的长度
}SSTable;
查找效率分析:
最好的情况下:第一次查找直接找到目标元素,即29,时间复杂度为O(1)
最坏的情况下:需要一直查找到最后,或者是查找失败的情况。每次查找,查找区域缩小一半,故时间复杂度为O(log2n)
(图片来自王道考研)