C语言——折半查找法

article/2025/8/24 0:51:47

一、使用场景

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

现在我们就将此思路实践一下看看是否能够找到该数字。给出一个包含十个元素的数组,里面包含了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 这种情况是查找次数最多的情况,都只需要四次查找即可完成,但是第一种方法查找需要七次,相比之下,足以见得折半查找法的高效性。

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


http://chatgpt.dhexx.cn/article/vRZ2SSeV.shtml

相关文章

利用Xpath进行动态定位元素

xpath中提供了三个非常好的方法来为我们定位部分属性值&#xff1a; 1、contains(a, b) 如果a中含有字符串b&#xff0c;则返回true&#xff0c;否则返回false 2、starts-with(a, b) 如果a是以字符串b开头&#xff0c;返回true&#xff0c;否则返回false 3、ends-with(a, b) 如…

WebDriver操作浏览器以及浏览器页面元素的方法

上篇文章是讲了WebDriver定位元素的方法&#xff0c;这篇文章就要讲操作了&#xff0c;本文内容篇幅可能会比较长&#xff0c;一个是因为要操作的项目比较多&#xff0c;另一个是我会将完整的代码放进来&#xff0c;总体原则上我还是追求尽量细致一些&#xff0c;以便能方便读者…

UN Comtrade(联合国商品贸易统计数据库)数据爬取Python代码——使用动态IP

目录 Virtual Private Network 代理服务器 测试代理IP是否生效 上一篇博文UN Comtrade&#xff08;联合国商品贸易统计数据库&#xff09;数据爬取Python代码讲了如何使用Python爬取UN comtrade数据&#xff0c;适用于少量数据爬取&#xff0c;由于网站对访问频率和访问量的…

uni-app点击按钮,生成列表元素

在jQuery里面&#xff0c;动态生成div元素需要进行html的拼接&#xff0c;拼接完成再将拼接的内容放到指定的div里面去&#xff0c;在vue中一般编写代码时都不需要操作DOM元素&#xff0c;那么点击按钮的时候&#xff0c;怎么动态生成自己想要的列表元素&#xff1f; 其实很简…

DOM(二)修改元素内容、属性

一个元素可以修改它的内容、属性和样式。 目录 DOM修改元素 1. 修改内容 2. 修改属性 DOM修改元素 1. 修改内容 &#xff08;1&#xff09;获取从修改元素开始标签到结束标签之间的原始的 HTML 内容 元素对象.innerHTML innerHTML 获取元素内容时&#xff0c;原样返回 H…

UN Comtrade(联合国商品贸易统计数据库)数据爬取Python代码

目录 Python代码 根据需求改写url 报错应对办法 UN Comtrade数据库关于中国台湾的数据 2021/9/28更新&#xff1a;最近有用户反馈下载会出现错误内容如下图&#xff0c;感谢用户三眼皮138帮忙找出错误。官方应该是更新API的使用了&#xff0c;在爬取数据是将url中的关键词m…

uni-app中动态修改伪类元素的样式

1.首先定义一个变量 2.在伪元素的父元素上面动态添加style&#xff0c;注意这个 设置的变量 --state 因为下面是 var 调用的所以需要加两个杠. 3.使用var调用变量 --state

selenium的常见表单元素操作

selenium的表单相关操作 selenium是浏览器自动化测试框架&#xff0c;是一个用于Web应用程序测试的工具&#xff0c;可以直接运行在浏览器当中&#xff0c;并可以驱动浏览器执行指定的动作&#xff0c;如点击、下拉、填充数据、删除cookie等操作&#xff0c;还可以获取浏览器当…

Web API:ResizeObserver——监听元素大小的变化

前言 最近突然发现了ResizeObserver 感觉挺有用的就简单学习了一下。 众所周知window.resize事件能帮我们监听窗口大小的变化。但是reize事件会在一秒内触发将近60次&#xff0c;所以很容易在改变窗口大小时导致性能问题。换句话说&#xff0c;window.resize事件通常是浪费的…

法规标准-UN R157标准解读

文章目录 UN R157是做什么的&#xff1f;ALKS系统一般要求动态驾驶任务本车道内行驶允许越过车道线执行LCP变道程序在EM期间进行回避车道交叉为应急车辆和执法车辆形成通道部分进入相邻车道&#xff0c;以绕过部分阻塞车道的障碍物 激活系统控制车速跟车停止前车减速、切入、切…

图像分割UNet系列------Res-UNet详解

图像分割unet系列------Res-UNet详解 1、Res-UNet要解决的问题2、Res-UNet主要网络结构3、引发的思考 Res-UNet发表于2018年&#xff0c;是UNet非常重要的改进版本之一。当然&#xff0c;Res-UNet同样是应用在医学图像分割领域-----视网膜血管分割。 1、Res-UNet要解决的问题 作…

U-Net

(1)使用全卷积神经网络。(全卷积神经网络就是卷积取代了全连接层&#xff0c;全连接层必须固定图像大小而卷积不用&#xff0c;所以这个策略使得&#xff0c;你可以输入任意尺寸的图片&#xff0c;而且输出也是图片&#xff0c;所以这是一个端到端的网络。 整个网络有23层卷积层…

Pytorch实战系列(一)——CNN之UNet代码解析

目录 1.UNet整体结构理解 1.1 UNet结构拆解 1.1.1 卷积层主体&#xff1a;两次卷积操作 1.1.2 左部分每一层&#xff1a;下采样卷积层 1.1.3 右部分每一层&#xff1a;上采样中部分跳跃连接卷积层 1.1.4 输入层和输出层 1.2 UNet结构融合 2.UNet Pytorch代码理解 2.1 …

快速理解Unet的网络结构

Unet 前言FCNUnet 前言 U-Net和FCN非常的相似&#xff0c;U-Net比FCN稍晚提出来&#xff0c;但都发表在2015年&#xff0c;和FCN相比&#xff0c;U-Net的第一个特点是完全对称&#xff0c;也就是左边和右边是很类似的&#xff0c;而FCN的decoder相对简单&#xff0c;只用了一个…

Unet网络解析

1 Unet网络概述 论文名称&#xff1a;U-Net: Convolutional Networks for Biomedical Image Segmentation 发表会议及时间 &#xff1a;MICCA ( 国际医学图像计算和 计算机辅 助干预会 议 ) 2 0 1 5 Unet提出的初衷是为了解决医学图像分割的问题。 Unet网络非常的简单&…

分割网络模型(FCN、Unet、Unet++、SegNet、RefineNet)

1、FCN https://blog.csdn.net/bestrivern/article/details/89523329《Fully Convolutional Networks for Semantic Segmentation》https://arxiv.org/abs/1411.4038 FCN是不含全连接层的全卷积网络&#xff0c;对图像进行像素级的分类&#xff0c;解决了图像的语义分割问题&a…

UNet网络解读

UNet解读 UNet论文UNet的简介代码解读DoubleConv模块Down模块Up模块OutConv模块 整个UNet参考资料 UNet论文 UNet论文地址 UNet的简介 UNet是一个对称的网络结构&#xff0c;左侧为下采样&#xff0c;右侧为上采样&#xff1b;下采样为encoder&#xff0c;上采样为decoder;四…

UNet网络

UNet 本博客主要对UNet网络进行讲解&#xff0c;以下为文章目录&#xff1a; UNet 原论文讲解网络结构数据集介绍评价指标损失计算代码 本文参考资料如下&#xff1a; UNet原论文 https://arxiv.org/pdf/1505.04597.pdfU-Net网络结构讲解(语义分割) https://www.bilibili.c…

U-Net网络详解

U-Net: Convolutional Networks for Biomedical Image Segmentation 原文地址&#xff1a;https://zhuanlan.zhihu.com/p/43927696 前言 U-Net是比较早的使用全卷积网络进行语义分割的算法之一&#xff0c;论文中使用包含压缩路径和扩展路径的对称U形结构在当时非常具有创新…