原理
最简单的二分查找原理:将数组有序后,找到数组的中间点mid,若要查找的值x>mid,则查找范围变为[mid+1,right];若x<mid,则查找范围变为[left,mid-1],直至找到x或区间变为0。
二分查找的时间复杂度为O(n)。
mid取值
mid的取值多数用(low+high)/2,但low+high过大会导致溢出(如Int上限溢出),因此用low+(high-low)/2或者low+((high-low)>>1)可以避免溢出情况。
局限性
二分查找的时间复杂度虽然有O(n),但是它也有一定的局限性:
1、用于二分查找的数组必须为有序数组,若为链表结构,无法支持随机访问,会导致时间复杂度过高。
2、数据量太小不适合二分查找,可直接用遍历算法(for循环)
3、数据量太大不适合二分查找,因数组需要使用连续的内存空间进行存储,可能没有太大的连续内存空间可以直接存储。
变体二分查找
1、查找第一个等于给定值的元素
主要分为三部分,定值小于a[mid],定值大于a[mid],这两种情况和基本的二分查找代码一致。
变体在于定值等于a[mid],这时不确定该mid是否是第一个等于定值的元素,因此进行条件判断。若mid==0(表示mid是第一个元素)或a[mid-1]!=value(表示mid的前一个元素不等于给定值),则说明mid就是第一个等于给定值的元素,否则区间缩小为[left,mid-1]。
2、查找最后一个等于给定值的元素
与1类似,主要在定值等于a[mid]时进行判断
3、查找第一个大于等于给定值的元素
主要在定值大于a[mid]时进行判断
4、查找最后一个小于等于给定值的元素
主要在定值小于a[mid]时进行判断
以上所有图片来源于王真——数据结构与算法之美