二分查找【详解】

在这里插入图片描述

本期介绍🍖
主要介绍:二分查找的简单思路,为什么必须在有序的前提下才能使用二分查找,该怎么用C程序来实现二分查找,二分查找的局限性👀。


文章目录

  • 1. 题目
  • 2. 思路
  • 3. 前提条件
  • 4. 编写程序


1. 题目

  在一个有序的数组中查找一个数,如果找到该数则返回下标,如果没有找到就返回没有找到。


2. 思路

  当我们要从一个序列中查找一个元素的时候,最快想到的方法就是顺序查找法(即:从前到后依次查找)。但这种方法过于无脑,就是暴力的把每个元素都排查一遍。元素个数少的时候还行,一旦元素个数多起来,效率是非常低下,所以在实际中这种查找的方法是被摒弃的。
  这里就不得不介绍一种简单且效率较高的查找方法了:二分查找法,又称折半查找法。但该方法是建立在有序的前提下的,基本思路就是:先找到那个有序序列的中间元素mid,然后拿它和要找的元素K进行比较,就可以初步判断K所在范围,既然查找范围已确定,自然该范围之外的元素就可以不用再查找了。
  因为二分查找每一次查找都可以缩减掉一半的查找范围,由此可以知道二分查找法的时间复杂度: log ⁡ 2 ( N ) \log_2(N) log2(N)。举个例子来解释该时间复杂度:若这里一共有2^32个元素,那么我在最坏的情况下也只需要32次就可以找到我想找的元素;而顺序查找法最坏的情况下,却需要查找 4,294,967,296‬ 次!!!,可见二分查找法的效率是非常之高的。


3. 前提条件

  都说二分查找法的前提条件是:查找的序列必须是有序的。我想大概很多小伙伴都会错误的认为有序是差值恒为1的顺序数列(就像这样1、2、3、4、5、6、7、8、9)。这只不过是有序的某一种情况罢了,那何为有序呢?即:该序列中的所有元素都是按照升序或者降序排列好的,元素与元素只间的差值虽然是随机的,但始终是在递增或递减(例如这样一个序列:3、12、24、31、46、48、66、79、82)。


4. 编写程序

  上面介绍完二分查找的思路和其限制条件后,接下来就该讲一讲如何去实现代码了。就用该案来讲解吧,下图所示序列中查找数字7,看是否能找到。
在这里插入图片描述

1. 第一步👀

首先,我们是要在一个有序的序列中查找某个元素的,那么该序列就必须有个连续的存储空间来存放,所以我们想到了用数组arr来存放。

#include<stdio.h>
int main()
{//存储递增的有序数列int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
}

2. 第二步👀

接下来,就该是找到序列的中间元素了,那该怎么找?我提供一个思路:通过对数组元素下标的计算来找到中间元素(中间元素下标mid=(数组最左边下标left + 最右边元素下标right)/ 2)。
在这里插入图片描述
程序如下所示:

#include<stdio.h>
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };//存储递增的有序数列int sz = sizeof(arr) / sizeof(arr[0]);//sz是数组元素的总个数int mid = 0;//存储中间元素的下标//左、右元素下标确定了被查找元素k的所在范围int left = 0;//最左边元素的下标int right = sz - 1;//最右边元素的下标int k = 0;//所要查找的元素kscanf("%d", &k);mid = (left + right) / 2;//计算中间元素的下标
}

3. 第三步👀

然后就拿中间元素和所查找元素k进行比较(这里我设置k = 7),发现7 > 5(中间元素),所以可以重新精确k的范围在中间元素之后了即:最左边元素应该为中间元素后面一个(left = mid + 1),最右边元素下标right不变。
在这里插入图片描述
但其他的情况也不能忽略,k < mid时范围重新精确到了mid的左半部分,就是(right = mid - 1),left不变;还有当k = mid时就意味着:找到所要找的那个数了,就是mid下标所对应的那个数。程序如下:

#include<stdio.h>
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };//存储递增的有序数列int sz = sizeof(arr) / sizeof(arr[0]);//sz是数组元素的总个数int mid = 0;//存储中间元素的下标//左、右元素下标确定了被查找元素k的所在范围int left = 0;//最左边元素的下标int right = sz - 1;//最右边元素的下标int k = 0;//所要查找的元素kscanf("%d", &k);mid = (left + right) / 2;//计算中间元素的下标//判断mid和看大小,重新精确k所在范围if (arr[mid] < k){left = mid + 1;}else if (arr[mid] > k){right = mid - 1;}else{printf("找到了\n");}
}

4. 第四步👀

然后就是重复的去执行:找中间元素下标,比较mid和k大小,从而更新迭代k新的范围,直到mid = k(即找到k了)为止。既然要实现重复的循环,程序中自然就要用到循环体了呀,那就加进去一个循环嘛。写道这里可还没算完呢,我们循环条件是什么还没确定呢!那循环条件如何确定呢?先思考个问题:若一直没找到我们所要找的元素,程序会以怎样的方式结束呢?
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
思考后我们发现在查找一个元素的时候,left下标和right下标会越来越靠近,甚至会指向一处,这个过程中left始终在right的左边(即:left <= right)。但如果一直找不到那个元素,两个下标必然会相互交错(即: left > right),这时循环结束。所以循环条件总结下来就是:while(left <= right)

程序最终完成,如下所示:

#include<stdio.h>
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };//存储递增的有序数列int sz = sizeof(arr) / sizeof(arr[0]);//sz是数组元素的总个数int mid = 0;//存储中间元素的下标//左、右元素下标确定了被查找元素k的所在范围int left = 0;//最左边元素的下标int right = sz - 1;//最右边元素的下标int k = 0;//所要查找的元素kprintf("请输入所要查找的数:");scanf("%d", &k);while (left <= right){mid = (left + right) / 2;//计算中间元素的下标//判断mid和看大小,重新精确k所在范围if (arr[mid] < k){left = mid + 1;}else if (arr[mid] > k){right = mid - 1;}else{break;}}if (left > right)printf("没有找到该数\n");else{printf("找到了\n");}
}

程序执行结果如下:
在这里插入图片描述
在这里插入图片描述


在这里插入图片描述

这份博客👍如果对你有帮助,给博主一个免费的点赞以示鼓励欢迎各位🔎点赞👍评论收藏⭐️,谢谢!!!
如果有什么疑问或不同的见解,欢迎评论区留言欧👀。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/739430.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【动态规划】代码随想录算法训练营第四十六天 |139.单词拆分,关于多重背包,你该了解这些! ,背包问题总结篇!(待补充)

139.单词拆分 1、题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 2、文章讲解&#xff1a;代码随想录 3、题目&#xff1a; 给定一个非空字符串 s 和一个包含非空单词的列表 wordDict&#xff0c;判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词…

3分钟彻底搞懂Web UI自动化测试之【POM设计模式】

为什么要用POM设计模式 前期&#xff0c;我们学会了使用PythonSelenium编写Web UI自动化测试线性脚本 线性脚本&#xff08;以快递100网站登录举例&#xff09;&#xff1a; import time from selenium import webdriver from selenium.webdriver.common.by import By dri…

Python SSH协议库之paramiko使用详解

概要 在网络编程中,远程操作是一项非常常见的需求,特别是在服务器管理和自动化任务执行方面。Python提供了许多库来实现远程操作,其中Paramiko是一个备受欢迎的选择。Paramiko是一个纯Python编写的SSH协议库,它提供了一种简单而强大的方式来执行远程命令、上传和下载文件等…

YUNBEE云贝-热烈祝贺Guo同学成功通过Oracle 19c OCP认证考试!

恭喜Guo同学在 #Oracle19c OCP 考试中取得了OCP证书&#xff01;该认证是Oracle公司的权威技术标准&#xff0c;适用于有资格为Oracle核心产品提供服务和支持的专业人员。尽管OCP认证考题随着版本变化&#xff0c;并且是全英文考试&#xff0c;对中文习惯的人来说有一定的难度&…

怎样将PPT转成文本格式?PPT文本一键生成文本格式 工作经验分享

在日常工作和学习中&#xff0c;我们经常需要将PPT文件转换为文本格式&#xff0c;以便更好地进行编辑、搜索和分享。下面&#xff0c;我将介绍2种常见的PPT转文本格式的方法&#xff0c;帮助大家轻松实现这一需求。 方法一、使用汇帮PDF转换器软件里的“PPT文件操作”菜单进行…

我们做的小工具,爆了!

好消息&#xff0c;好消息&#xff0c;江南皮革。。 开个玩笑&#xff0c;大家好&#xff0c;我是程序员鱼皮。 前段时间我在公众号发文宣传了团队新开发的小工具《代码小抄》&#xff0c;这是一个简单易用的代码分享工具&#xff0c;可以快速、跨设备地自由分享代码。 网址&…

使用Office的小伙伴一定要把这个打开!关键时候能保命

使用电脑办公的小伙伴一定离不开Office。很多小伙伴在使用Office的时候&#xff0c;基本上都是双击打开对应的软件&#xff08;Word/Excel/Powerpoint&#xff09;就直接使用。 这种直接打开之后就使用的习惯很不值得提倡。除非你要记录的东西是一分钟就能完成的。 小白在企业上…

在四维轻云中,能够上传哪些地理空间数据?

四维轻云是一款地理空间数据在线管理平台&#xff0c;支持各类地理空间数据的在线管理、浏览及分享&#xff0c;用户可不受时间地点限制&#xff0c;随时随地上传、管理、查看及分享各类地理空间数据。平台具有项目管理、场景搭建、素材库等功能模块&#xff0c;支持在线协作管…

《JAVA与模式》之合成模式

系列文章目录 文章目录 系列文章目录前言一、合成模式二、安全式合成模式的结构三、透明式合成模式的结构四、两种实现方法的选择前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享…

有哪些知识管理软件适合中小型企业,高管必看!

在经济加速发展的今天&#xff0c;企业对信息和知识的管理需求越来越高&#xff0c;于是&#xff0c;各类知识管理软件应运而生。对于中小型企业来说&#xff0c;选择一款高效、省时、方便的知识管理软件尤其重要。下面&#xff0c;我为大家推荐三款知识管理软件&#xff0c;适…

力扣L6--- 两数之和(java版)--2024年3月12日

1.题目 2.知识点 注1&#xff1a;在Java中&#xff0c;数组的长度不是通过调用一个方法获得的&#xff0c;而是通过一个属性直接获得的。因此&#xff0c;正确的语法是nums.length而不是nums.length()。 所以应该使用int m nums.length; 注2&#xff1a;return new int[]{i,…

SpringBoot注解事务失效列举总结

Spring事务注解 Transactional失效 常规写法不会有脏数据插入。 情景一、内部调用导致事务失效 数据库中出现测试回滚的脏数据 导致该问题原因为spring执行方法数据库操作的时候会生成一个动态代理类去执行代理类的该方法&#xff0c;代理类在执行updateUser时&#xff0c;执…

2024-3-11-C++作业

1>试编程 要求&#xff1a; 提示并输入一个字符串&#xff0c;统计该字符中大写、小写字母个数、数字个数、空格个数以及其他字符个数 源代码: #include <iostream>using namespace std;int main() {string s;cout << "请输入字符串&#xff1a;"…

CentOS 7 基于开源项目制作openssh 9.7p1二进制rpm包(内含ssh-copy-id、显示openssl版本信息)—— 筑梦之路

可参考之前的文章&#xff1a;CentOS 5/6/7 基于开源项目制作openssh 9.6p1 rpm包—— 筑梦之路_centos6 openssh9.6rpm-CSDN博客 2024年3月12日 植树节制作&#xff0c;相关文件见我的资源

力扣刷题日志-Day2 (力扣151、43、14)

151. 反转字符串中的单词 给你一个字符串 s &#xff0c;请你反转字符串中 单词 的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开 思路&#xff1a;根据题目大意&#xff0c;空格之间的就是一个单词&#xff0c;所以我们需要利用…

swagger踩坑之请求类不显示具体字段

swagger踩坑之请求类不显示具体字段 省流&#xff1a;枚举字段需要加上ApiModelProperty注解 过程复现&#xff1a; TestEnum 枚举不加注解&#xff0c;swagger的UI类不显示详细字段 Data Accessors(chain true) ApiModel(value "test对象", description &quo…

通过Office Web Viewer站点在线展示Office文档内容

方法&#xff1a; https://view.officeapps.live.com/op/view.aspx?src经Url编码的文档线上Url地址 比如&#xff1a; //以下地址来自一份旧项目代码&#xff0c;可见用的就是该方案function OfficeFileViewOnline(url, file_type, file_name) {url "http://14.23.112.2…

算法——哈希王

242.有效的字母异位词 力扣题目链接(opens new window) 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 示例 1: 输入: s "anagram", t "nagaram" 输出: true 示例 2: 输入: s "rat", t "car&qu…

配置vscode环境极简版(C/C++)(图文)

前言 众所周知&#xff0c;vscode是一个代码编辑器&#xff0c;不能直接编译运行我们敲的代码&#xff0c;必须提前配置好环境&#xff0c;而这也是劝退一众小白的一大重要因素&#xff0c;下面我想以一种提纲挈领的方式带大家走一遍从配置环境到运行实操代码的全过程。 安装…

Java项目:基于Springboot+vue实现的付费自习室系统设计与实现(源码+数据库+毕业论文)附含微信小程序端代码

一、项目简介 本项目是一套基于Springbootvue实现的付费自习室系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、…