算法分析 | 细说二分查找(折半查找)算法

Posted 挑战算法与程序设计

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法分析 | 细说二分查找(折半查找)算法相关的知识,希望对你有一定的参考价值。

全文共 880 字,阅读文本大概需要 3 分钟。

算法分析 | 细说二分查找(折半查找)算法(1)


二分查找引例



今天要为大家介绍的是一种很常用的算法,先给一个引例我们在写程序或者生活的时候经常会遇到这样一类问题:在一个队列/数组中查找一个数是不是存在,例如在下面这个数组中,查找 8 是不是存在:


算法分析 | 细说二分查找(折半查找)算法(1)


如果在不考虑效率的的话,我们常规都会想就按照顺序的方法去查看,也就是上文中我所说的暴力枚举法,依次查看 a[0],a[1],...,a[n-1],按顺序检查是不是 8 ,这种如果是整个长度为 n 的话平均查找的长度为 n/2。


如果对应的数组是一个有序的,比如就是上面的图片的那种【1,2,3,4,5,7,8,10,11,13】的话我们,我们就出现了一种效率更高的算法,叫做二分查找,例如我们还是查找上面的 8 :


算法分析 | 细说二分查找(折半查找)算法(1)


简单的讲就是在每一次在一个递增数列中查找中间值,用中间值与要查找的数比较然后确定下一个区间实在左边还是右边。这样我们可以得出一个结论:其输入是一个有序的元素列表,如果要查找的元素包含在列表中,二分查找返回其位置;否则返回一个特定值。(每一次区间缩小一半也叫:折半查找)


举个栗子



对于上面的那种类型的引出我们,我们下面来看一个最简单的二分查找算法:假设数组 a[0],a[1],...,a[n-1] 是一个单调递增的,并且没有重复的值,要求在数组 a 中查找 x, 如果 x 存在,返回对应的下标,否则输出 -1。


代码是这个样子:


算法分析 | 细说二分查找(折半查找)算法(1)


main 函数中的代码就不讲了,主要讲一下 binary_search 函数中的代码,三个参数第一个使用指针传递的 数组a, 第二个是 数组的长度n, 第三个是需要查找的值x。返回值为数组的下标,如果查找不到返回 -1;


二分查找的过程实际上就是不断缩小范围的过程。所以我们用l和r两个变量来表示当前范围的左端点和右端点,也就是说当前x可能存在的范围是 a[left]~a[right] 之间。注意这个范围是包含 a[left] 和 a[right] 的,是个闭区间,所以 left 的初始值是0,right 的初始值是n-1。第8行 ans 的初始值是-1,也就是没有找到x的返回值。

看代码 第 8 行 到第17 行就是在每一次比较每一次缩小一半的区间,形象过程如下图所展示。第 10 行的输出语句是为了能直观看到代码运行的过程。代码获取方式放在文末。


看代码第 9 行 这里使用 int mid = left+(right -left)/2  的一种int mid = (left+right)/2 的一种改进,对应 int 的范围是 21474836458,对于一般的数字不会超出范围,但是会有一种可能 left = 1999999999 ,right = 2000000000,这样两个都没有超过范围,但是如果相加直接爆掉。


最后一点,就是二分查找的算法大家都一样;但是程序实现起来每个人都有不同的写法。如果你上网找一找二分查找的代码,可能会找到很多个版本。这些版本会有一些细节不同。大家只需要记得一个就可以应付所有场景。


代码获取



为了方便看官们的代码获取,小编在后台放了获取方式。如果感觉小编的文章有点意思那就点点赞,转发朋友告诉他/她你在学习(至少一位朋友),扫码订阅此号,后台回复: 二分01  即可获得。


更新了每周分享一本电子书,这周分享的是《编程之美》。

关注后台回复关键词:每周一本电子书  即可获赠。

---end---



以上是关于算法分析 | 细说二分查找(折半查找)算法的主要内容,如果未能解决你的问题,请参考以下文章

C言语二分查找(折半查找)算法及代码

C语言试题177之实现二分查找算法,折半查找算法

细说算法之二分查找算法

二分查找(折半查找)算法详解(C语言实现)

二分查找(折半算法实现)

python实现二分查找(折半查找)算法