【算法详解 | 二分查找】详解二分查找 \ 折半查找高效搜索算法 | 顺序数组最快搜索算法 | 递归循环解决二分查找问题

二分查找

by.Qin3Yu

本文需要读者掌握 顺序表 的操作基础,完整代码将在文章末尾展示。

顺序表相关操作可以参考我的往期博文:
【C++数据结构 | 顺序表速通】使用顺序表完成简单的成绩管理系统.by.Qin3Yu

文中所有代码使用 C++ 举例,且默认已使用部分头文件和 std 命名空间:

#include <iostream>
#include <vector>
using namespace std;

概念速览

二分查找概述

  • 二分查找 算法属于 搜索算法 的一种。它是一种高效的搜索算法,用于在有序数组或列表中查找特定元素的位置。
  • 二分查找的基本思想是通过将目标值与数组中间的元素进行比较,从而将搜索范围缩小一半。如果目标值小于中间元素,则继续在左侧子数组中进行二分查找;如果目标值大于中间元素,则继续在右侧子数组中进行二分查找;如果目标值等于中间元素,则直接返回该位置。通过重复这个过程,最终可以找到目标值或确定其不存在于数组中。
  • 二分查找算法的时间复杂度为 O(log n) ,且不需要额外存储空间。

二分查找通常被使用于符合以下条件的以下场景:

  1. 数组或列表是 有序 的;
  2. 静态 数据结构;
  3. 数据量较
  4. 只需要 快速确定 元素是否存在。

算法详解

逻辑解析

  • 二分查找,就是不断的对搜索范围进行折半,从而缩小搜索范围,我们用下面的数组来进行说明:

在这里插入图片描述

  • 在上面的有序数组中,我们要查找数组内是否存在值 31 ,于是我们可以如下图所示,使用三个指针,一个指向数组的最左端,一个指向数组的最右端,一个指向数组的中间。

在这里插入图片描述

  • 我们使用 leftrightmid 分别表示左、右、中指针,当前 mid 指向的值为 26 ,因为数组是有序数组,所以可以得知,我们要查找的值 31 一定在 26右侧 ,因此,我们将左指针 left 指针指向 mid 的后一位元素,然后重新计算出 mid 指针的位置:

在这里插入图片描述

  • 如图所示,当前 mid 指向的值为 44 ,比 31 小,因此我们要查找的 31 一定在 44 的左侧,因此,我们把右指针 right 指向 mid 的前一位元素,然后重新计算 mid 的位置:

在这里插入图片描述

  • 同理,mid 指向的值 30 小于 31 ,所以我们把 left 移到 mid 的后一位,然后重新计算 mid 的位置:

在这里插入图片描述

注意:在二分查找中,rightleft 重合属于正常现象,表示搜索范围只有一个数字。

  • 此时,我们再检查 mid 所指的值,就是我们要查找的 31,于是我们返回出对应的结果,表示成功查找到元素。
  • 我们在上一步的例子中做出一点修改,假如数组中没有我们要查找的值 31 ,则会产生一种情况,即 left 跑到 right 的右边,代表数组中没有我们要查找的元素:

在这里插入图片描述

代码实现

  • 在下例中,我们使用 vector 顺序表来保存数据,然后使用 binarySearch 方法表示二分搜索:
int main() {vector<int> data = {1,7,9,11,14,19,20,26,29,30,31,44,45,52,59};int target = 31;int result = binarySearch(data, target);
}
  • 首先,我们要声明左右指针,左指针指向数组最前端,即索引为 [0] ,右指针指向数组最右端,即索引为 [长度-1]
int left = 0;
int right = arr.size() - 1;
  • 在上文中我们提到,如果 left 指针移动到了 right 指针右边,则代表数组内没有对应的值,则返回 -1 ,表示没有目标值:
while (left <= right) {...
}
return -1;
  • 接下来,我们要根据左右指针计算出中间指针 mid ,即左指针加上两指针之和除二:
int mid = left + (right - left) / 2;
  • 最后,我们来判断 mid 指针所指值与查找值的关系,如果相等,则返回成功目标值的索引:
if (arr[mid] == target) {return mid;  // 找到目标,返回索引
}
  • 如果 mid 所指值比目标值小,则证明目标值只可能在 mid 右边,我们将 left 指针移到 mid 指针后一位,从右侧子数字开始查找:

在这里插入图片描述

else if (arr[mid] < target) {left = mid + 1;  // 继续在右侧子数组中查找
}
  • 相反,如果 mid 所指值比目标值大,则证明目标值只可能在 mid 左边,我们将 right 指针移到 mid 指针前一位,从左侧子数字开始查找:

在这里插入图片描述

else {right = mid - 1;  // 继续在左侧子数组中查找
}
  • 将上述代码做出结合后,便是完整的二分查找代码,具体如下文所示。

完整算法代码

#include <iostream>
#include <vector>
using namespace std;int binarySearch(const vector<int>& arr, int target) {int left = 0;int right = arr.size() - 1;while (left <= right) {int mid = left + (right - left) / 2;  // 防止(left + right)出现溢出if (arr[mid] == target) {return mid;  // 找到目标,返回索引} else if (arr[mid] < target) {left = mid + 1;  // 继续在右侧子数组中查找} else {right = mid - 1;  // 继续在左侧子数组中查找}}return -1;  // 没有找到目标,返回-1
}int main() {vector<int> data = {1,7,9,11,14,19,20,26,29,30,31,44,45,52,59};int target = 31;int result = binarySearch(data, target);if (result != -1) {55cout << "成功查找到对应值!" << result << endl;} else {cout << "找不到对应值。" << endl;}return 0;
}
至此,二分查找的所有内容讲解完毕(=
感谢您的阅读(=
CSDN.by.Qin3Yu

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

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

相关文章

Dash :一个超漂亮的 python Web库!

你好&#xff0c;Dash 是一个非常方便的 Python 库&#xff0c;它可以非常非常帮助你构建基于 Web 的应用程序&#xff0c;而且最棒的是你无需使用 JavaScript&#xff01; 不仅如此&#xff0c;Dash 还是一个专门用于创建分析 Web 应用程序的用户界面库。 如果你是一个使用 …

前端JavaScript篇之对对象与数组的解构的理解、如何提取高度嵌套的对象里的指定属性?

目录 对对象与数组的解构的理解如何提取高度嵌套的对象里的指定属性&#xff1f; 对对象与数组的解构的理解 对象与数组的解构是一种通过模式匹配的方式&#xff0c;从对象或数组中提取值&#xff0c;并将其赋给变量的过程。它可以让我们以一种简洁的方式访问和使用对象或数组…

嵌入式学习第十六天

C语言小项目&#xff1a; 制作俄罗斯方块小游戏&#xff08;1&#xff09; 主函数部分&#xff08;1&#xff09; #include <stdio.h> #include <unistd.h> #include <signal.h>extern int InitBoarder(void); extern int SetBoarder(void); extern int S…

2023年算法SAO-CNN-BiLSTM-ATTENTION回归预测(matlab)

2023年算法SAO-CNN-BiLSTM-ATTENTION回归预测&#xff08;matlab&#xff09; SAO-CNN-BiLSTM-Attention雪消融优化器优化卷积-长短期记忆神经网络结合注意力机制的数据回归预测 Matlab语言。 雪消融优化器( SAO) 是受自然界中雪的升华和融化行为的启发&#xff0c;开发了一种…

Unity DOTween插件常用方法(二)

文章目录 1.3 动画设置1.4 动画队列 Sequence1.5 动画回调函数1.6 等待函数&#xff08;协程中使用&#xff09; 1.3 动画设置 SetLoops 设置循环动画&#xff1b; 参数&#xff1a; loops&#xff1a;指定循环的次数&#xff0c;设置为 -1 表示无限循环&#xff1b; loopType…

由数据插入超长引起的问题——了解GaussDB和openGauss的字符集

前言 故事是这样开始的。我们的小DEMO项目的数据库版本从openGauss 2.1.0升级到了5.0.0版本。升级后进行功能验证的时候&#xff0c;测试同学发现个BUG&#xff0c;原来通过gs_restore导出来的数据再导入时报超长&#xff0c;插入失败了&#xff0c;如下图所示&#xff0c;nva…

如何让你的 Jmeter+Ant 测试报告更具吸引力?

引言 想象一下&#xff0c;你辛苦搭建了一个复杂的网站&#xff0c;投入了大量的时间和精力进行开发和测试。当你终于完成了测试并准备生成测试报告时&#xff0c;你可能会发现这个过程相当乏味&#xff0c;而对于其他人来说&#xff0c;它可能也不那么吸引人。 但是&#xf…

【RT-DETR改进涨点】ResNet18、34、50、101等多个版本移植到ultralytics仓库(RT-DETR官方一比一移植)

👑欢迎大家订阅本专栏,一起学习RT-DETR👑 一、本文介绍 本文是本专栏的第一篇改进,我将RT-DETR官方版本中的ResNet18、ResNet34、ResNet50、ResNet101移植到ultralytics仓库,网上很多改进机制是将基础版本的也就是2015年发布的ResNet移植到ultralytics仓库中,但是其实…

【Qt基本功修炼】Qt线程的两种运行模式

1. 前言 QThread是Qt中的线程类&#xff0c;用于实现多线程运行。 QThread有两种工作模式&#xff0c;即 消息循环模式无消息循环模式 两种模式分别适用于不同的场景。下面我们将从多个方面&#xff0c;讲解QThread两种工作模式的区别。 2. 消息循环模式 2.1 实现原理 Q…

【misc | CTF】攻防世界 2017_Dating_in_Singapore

天命&#xff1a;这次终于碰到了算是真正的misc题目了 下载附件&#xff0c;打开是PDF&#xff0c;我一开始以为是flag隐写在PDF里面了 虽然也不奇怪&#xff0c;应该是可以的&#xff0c;毕竟PDF有xss漏洞也是可以的 言归正传&#xff0c;打开PDF 看着新加坡的日历&#xff…

大数据平台-可视化面板介绍-Echarts

应对现在数据可视化的趋势&#xff0c;越来越多企业需要在很多场景(营销数据&#xff0c;生产数据&#xff0c;用户数据)下使用&#xff0c;可视化图表来展示体现数据&#xff0c;让数据更加直观&#xff0c;数据特点更加突出。 目录 01-使用技术 02- 案例适配方案 03-基础…

【BUG】golang gorm导入数据库报错 “unexpected type clause.Expr“

帮同事排查一个gorm导入数据报错的问题 事发现场 ck sql CREATE TABLE ods_api.t_sms_jg_msg_callback_dis (app_key String DEFAULT COMMENT 应用标识,callback_type Int32 DEFAULT 0 COMMENT 0送达&#xff0c;1回执,channel Int32 DEFAULT 0 COMMENT uid下发的渠道,mode…

EasyExcel通用导入 | 简单封装

0. 前言&#xff1a;1. 基本思路&#xff1a;2. 调用代码&#xff1a; 0. 前言&#xff1a; 之前做了好几个导入&#xff0c;用EasyExcel每次都要定义监听器去处理&#xff0c;就想能不能做个通用的方式&#xff0c;如下 1. 基本思路&#xff1a; 导入无非主要就是参数校验和数…

MacBook安装虚拟机Parallels Desktop

MacBook安装虚拟机Parallels Desktop 官方下载地址: https://www.parallels.cn/pd/general/ 介绍 Parallels Desktop 被称为 macOS 上最强大的虚拟机软件。可以在 Mac 下同时模拟运行 Win、Linux、Android 等多种操作系统及软件而不必重启电脑&#xff0c;并能在不同系统间随…

数据结构------算法时间复杂度

通俗的理解一下算法的时间复杂度 主要是看这个速发的时间性能&#xff0c;从这个算法规模入手&#xff0c;具体的看一下这个算法的所需时间与这个算法规模的关系 关系有 O(1) 常数次 1次 2次。。。。。。 O(n)一个for循环 O(n^2)两个for循环&#xff08;嵌套&#xff09; O(mn)…

【动态规划】【数学】1388. 3n 块披萨

作者推荐 【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数 本文涉及知识点 动态规划汇总 LeetCode1388 3n 块披萨 给你一个披萨&#xff0c;它由 3n 块不同大小的部分组成&#xff0c;现在你和你的朋友们需要按照如下规则来分披萨&#xff1a; 你挑选 任…

异步编程,到底有什么用?

关键词&#xff1a;高性能、架构设计、异步思想、场景落地 文章导读 场景切入 先来看一个日常生活快递寄件场景&#xff0c;从寄件人&#xff08;寄件&#xff09;到收件人&#xff08;收件&#xff09;&#xff0c;全流程如下 当你准备寄送一个包裹时&#xff0c;通常你可以…

ManticoreSearch-(安装配置,集群搭建)-学习总结

ManticoreSearch-(安装配置)-学习总结 基础概念安装搭建集群搭建(基于K8S) 原文地址 https://blog.csdn.net/liuyij3430448/article/details/135955025 基础概念 Manticore Search是一个专门为搜索设计的多存储数据库&#xff0c;具有强大的全文搜索功能&#xff0c;适用于…

Python代码重构库之rope使用详解

概要 Python是一门强大的编程语言,但在大型项目中,维护和重构代码可能会变得复杂和困难。为了提高开发人员的效率和准确性,有许多工具可用于辅助代码重构和智能代码补全。其中之一是Python Rope。 Python Rope是一个用于Python编程语言的强大工具,它提供了丰富的功能,包…

EasyX图形库学习(一)

目录 一、easyX图形库基本介绍 1、easyX的原理 2、easyX的安装 3、easyX的颜色&#xff08;RGB颜色模型&#xff09; 颜色模型相关函数: 4、easyX的坐标 二、相关函数介绍: 绘图设备相关函数&#xff1a; 图形颜色及样式设置相关函数: 图形绘制相关函数: 文字输出相关…