一、使用场景

假如现在有一组数据,你想要查询这个具体某一个数据在这一堆数据中的所在位置,这个时候就需要程序在这一组数据中,找到与想要查找的目标数据相匹配的那个数据,然后返回相对应的位置。如果将问题再细化简化一点,假如现在有一组有顺序的数字,需要你编写程序找到其中一个数字所在的位置。了解需求之后,我们脑海中一般首先浮现的思路便是,编写一个数组,然后将数字一个个进行匹配,最后找到这个数字的位置,返回该位置,问题解决。

现在我们就将此思路实践一下看看是否能够找到该数字。给出一个包含十个元素的数组,里面包含了1,2,3,4,5,6,7,8,9,10,然后尝试在其中找到数字7对应的位置,代码如下所示:

上面的代码使用了flag作为一个标志数,因为成功找到后break跳出循环继续执行,但是如果查找的是一个不存在该数组中的数字时,对上面数据全部进行查找之后也会结束循环执行,此时如果没有标志数,程序就无法判断是因为哪种原因跳出了循环结构。所以定义一个变量flag进行判断:如果成功找到,flag的值为1,否则为0,程序就能通过if语句进行判断是哪种情况,判断是否输出找不到情况下的语句。

我们发现最后是可以实现这个目标的,成功找到了数字7在这个数字中对应的位置:7.(这个位置是指在数字的位置而不是数组中的下标)。

但是这样一个个数字进行匹配,虽然能找到对应位置,但是假如现在有100或者1000甚至10000个数字,然后想要找到比较靠后的一个数字对应的位置时,这种方法就显得有些许“笨拙”了,不够灵活和简便,要将所有数字从头到尾一个个进行匹配,直至找到为止。此时就需要使用一个更加简便更加快速的方法——折半查找法,或者叫做二分查找法。

二、如何实现折半查找法

假如一天你的同学买了一双球鞋,只告诉你这双鞋在一千以内,然后让你猜这双鞋价格是多少,你会怎么做?可能有少部分人会上来就给这位朋友一拳,然后一顿输出“你买鞋又不是买给我,还**让我猜价钱,凡尔赛你**,我******”,但是大多数人还是会选择正确的做法:从中间数500开始猜,而不是像上面的做法一样,真的就傻傻的从1,2,3开始猜到1000。所以折半查找法的思想也是如此。

我们从这一组有序数字中,取其中位数与我们查找的目标数进行匹配,如果正好一发入魂,那就直接找到了该数,但是即使大概率不正确,我们也可以直接干掉一半的数据。举个例子:假如现在有个数组是1-1000,目标数是777,那么我中位数是500,进行比较之后是比目标数更小,那就说明目标数的位置只可能在中位数往上,而不能在500之下,那么500以下的数字就全部被干倒了,这一次查找就可以消灭掉一半数据,而上面的做法一次只能消灭一个数字,效率相比之下就产生了很明显的差距了。然后第一次查找后再进行第二次折半,取750进行比较,这次还是比目标数小,但是仍然干掉了一半数据,依次进行下去,只需使用少数次数查找便可以从大量数据中找到。

现在还是使用上面的例子,示例以下折半查找法:

上面代码中先定义了一个左下标和右下标,从而定义出中位数的下标。每次查找之后,如果目标数 > 中位数,那么目标数只会出现在中位数往上的位置,那么此时右下标不需变动,左下标应该是中位数的下标 +1,再次对左右下标相加除以2,取得剩下数据的中位数作为新的中位数进行下一次查找。如果目标数 < 中位数,那么目标数只会出现在中位数之下的位置,那么此时左下标不需变动,右下标应该是中位数的下标 -1,然后再次取新的中位数,以此类推进行查找,所以使用while循环。

第一次查找的图示如下,第一次查找之后可知 k > 中位数,所以 k 的位置只可能出现在中位数的右边,此时我们的第二次查找想要从中位数的右边第一个数开始找起,所以此时左下标应该是 mid + 1。

所以第二次查找如下,可知现在 k < 中位数,所以只可能出现在中位数的左边,此时我们希望下次查找从中位数的左边第一个数开始,所以此时右下标为 mid - 1。

然后后续查找都如上图所示,直至左右下标交错(left > right)或者相等(left = right),便是循环结束的标志。

三、总结

折半查找法每一次查找都可以判断一半数量的数据是否匹配,效率比第一种方法高效很多。k = 7 这种情况是查找次数最多的情况,都只需要四次查找即可完成,但是第一种方法查找需要七次,相比之下,足以见得折半查找法的高效性。

但是折半查找法也是需要前提条件才可以使用的,就是要求查找的这组数据必须是有序的,倒序和顺序都可以。面对无序的数据,折半查找法就失效,这也是相较于第一种方法的不足之处,两种方法各有所长,须根据不同情况进行使用。

C语言——折半查找法相关推荐

  1. c语言折半查找法找字符,C语言简单实现折半查找法

    近期研习C语言,谭浩强<C语言程序设计(第2版)>P167.6原题: 有15个数按由大到小顺序存放在一个数组中,输入一个数,要求用折半查找法找出该数是数组中第几个元素的值.如果该数不在数组 ...

  2. c语言折半查找法找字符,折半查找法(C语言)

    折半查找法(C语言) #include #define max 20 int binary(int x,int list[],int n)               /*从list[]中查找x*/ ...

  3. c语言折半查找法例题6,折半查找法--C语言谭浩强版练习6.9

    不多说,直接上图. 本程序来源于百度百科――折半查找法 #include #include int main(void) { int arrayA[15]={2, 4, 5, 7, 8, 10, 12 ...

  4. C语言折半查找法(超详细)

    折半查找法仅适用于对已有顺序的数组.数据进行操作!!!(从小到大)自我总结:折半查找法就是相当于(通过改变low或high的大小)把中间位置指到了key那个数那里,所以mid应该处于循环里面,即mid ...

  5. c语言折半查找法_C语言学习|选择法排序及折半查找法查找

    数组名作为函数参数示意图 交换法排序,读者只要仔细研究一下这个算法就不难发现,其排序效率较低.因为在第i轮(i=0,1,2--,n-2)比较中,第i+1个数和后面所有的数都要进行一次比较,每进行一次比 ...

  6. c语言折半查找法程序,C语言基础:二分查找法演示代码

    2015-11-07 06:30:02 阅读( 276 ) #include int binary_search(int array[], int value, int size) { int fou ...

  7. c语言折半查找法找字符,C语言折半查找法练习题冒泡排序

    MongoDB管理工具的插件系统 MongoDB管理工具  MongoCola的开发已经进入第三个年头了. 官方对于C#驱动的投入不够导致了很多东西都必须自己实现,但是不管怎么样,工具现在已经很强大了 ...

  8. C语言:有N个数从小到大的顺序存放在一个数组中,输入一个数,要求用折半查找法找出该数是数组中第几个数。如果不在数组中,打印“not found”。

    /*有N个数从小到大的顺序存放在一个数组中,输入一个数,要求用折半查找法找出该数是数组中第几个数.如果不在数组中,打印"not found".*/#include<stdio ...

  9. 每日C语言(The 7th day)——折半查找法

    太久没有更新了,偷懒了,趁着开学前多发几篇(偷笑) 老样子先上题目 T(题目):假设有若干个由大到小排序的数已经顺序存放在一个数组中,现输入一个数x,请用折半查找法找出该数是数组中哪个元素的值.找到则 ...

最新文章

  1. 基于软件开发对嵌入式开发的思考
  2. yolact实时分割
  3. js实现图片无缝循环跑马灯
  4. 【转】Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask
  5. 【NLP机器学习基础】从线性回归和Logistic回归开始
  6. Application.DoEvents()的使用
  7. MySQL部署2002_MySQL入门02-MySQL二进制版本快速部署
  8. x86服务器当虚拟化的存储,X86服务器虚拟化实施方案.doc
  9. Linux高性能server编程——高级I/O函数
  10. [Flags]标识的Enum不能使用Html.GetEnumSelectList方法
  11. php用a什么软件来下载,AMQB官方PHP库
  12. 云端远程Ubuntu系统进行无桌面Web浏览器自动化测试
  13. Hyper-V 3.0网络虚拟化PART 4:私有交换机
  14. Sqoop导入数据发生数据倾斜问题 及更好解决
  15. 跟燕十八学习PHP-第二十八天-union用法深入讲解
  16. Excel获取目标时间点/日期的方法
  17. 传奇私服架设入门教程分享
  18. inputBox 与 Application.inputBox 的用法与区别。
  19. 无心剑中译泰戈尔《漂鸟集(1~10)》
  20. 2022-2027(新版)中国工业5G技术行业发展动态与前景规划分析报告

热门文章

  1. 苹果IOS应用上架遇到的问题及处理方法记录
  2. 【C语言-B站鹏哥】初识指针
  3. 数据指标体系建设思考(二)
  4. 计算机主板电池没电什么情况,事实:如果计算机主板电池没电了怎么办?解决计算机主板电池没电的问题...
  5. Zbrush基础操控与快捷键介绍
  6. 常用的矩阵范数和矩阵导数
  7. 怎么以管理员身份运行cmd?以管理员身份运行cmd方法介绍
  8. 用于游戏开发的 8 大 JavaScript 引擎
  9. 图形学-变换(平移矩阵,旋转矩阵,缩放矩阵,线性变换,仿射变换,齐次坐标)
  10. XML扩展性标记语言