vlambda博客
学习文章列表

二分查找算法,你真的了解吗?


二分查找算法
二分查找算法,你真的了解吗?

01基本思想



输入是一个有序的元素列表

如果要查找的元素包含在列表中,二分查找返回其位置;否则返回null。


首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。



摘自百度百科

二分查找算法,你真的了解吗?
02Python代码

二分查找算法,你真的了解吗?

运行结果:

二分查找算法,你真的了解吗?

二分查找算法,你真的了解吗?
03容易忽略的问题

I


while循环的终止条件low<high还是low<=high?

当数组只有一个元素时,此时low=high,使用low<high作为循环终止条件会漏掉这一个元素!

II


mid=(low+high)/2时会存在溢出。

计算机在进行计算时,会先计算low+high的值,16位的整型数字最大为65535,假设此时low=30000,high=40000,二者的和为70000,超过整型最大值,产生溢出!

使用mid=low+(high-low)/2可解决溢出问题!


Python3.x版本中执行的是“真”除法,会导致float代替整数,所以会出现如下错误:

TypeError: list indices must be integers or slices, not float

所以在Python3.x版本中可表示为

(low+high)//2

III

算法时间复杂度为O(logn)   底数为2

假设要画一个网格,包含16个格子

方法一:

每次画一个的方式画16个格子,需要操作16次

运行时间是O(n)


方法二:

将纸折起来

对折一次就是一次操作,第一次对折相当于画了两个格子!

折四次即可获得16个网格!

运行时间是O(logn)


算法运行时间并不以秒为单位,从其增速的角度度量!

算法的速度指的并非是时间,而是操作数的增速。

谈论算法的速度时,我们说的是随着输入的增加,其运行时间将以什么样的速度增加。



摘自书籍《算法图解》

二分查找算法,你真的了解吗?
04拓展实践


有时候有序数组并不是完全顺序排列的,例如[1,2,3,3,5,9],这个时候使用二分查找并不能完全满足查找需求。

例如我想查找第一个数字3的索引2,表示比3小的数字有2个。结果查找到的是第二个数字3的索引3,这就牵扯到寻找左右边界的二分查找了!


二分查找算法,你真的了解吗?
寻找左侧边界的二分查找

二分查找算法,你真的了解吗?

二分查找算法,你真的了解吗?
寻找右侧边界的二分查找

END