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

news2024/11/25 4:42:20

二分查找

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) {55
        cout << "成功查找到对应值!" << result << endl;
    } else {
        cout << "找不到对应值。" << endl;
    }

    return 0;
}

至此,二分查找的所有内容讲解完毕(=
感谢您的阅读(=
CSDN.by.Qin3Yu

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

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

相关文章

Linux管道、网络管理和远程连接

这次来说一下Linux管道、网络管理与远程连接相关的一些内容&#xff0c;如下。 一、管道&#xff08;重点&#xff09; 1、管道符 用 “|”&#xff08;竖线&#xff09;表示。 作用&#xff1a;管道是一种通信机制&#xff0c;通常用于进程间的通信。它表现出来的形式将前…

ZigBee学习——在官方例程基础实现点灯

IAR版本 :10.10.1 Z-stack版本 :3.0.2 文章目录 一、买的板子原理图二、实现过程2.1 重定义LED的物理映射(HAL层)2.2 创建LED事件(应用层)2.2.1 定义用户事件2.2.2 修改zclGenericApp_event_loop() 2.3 触发事件 一、买的板子原理图 二、实现过程 2.1 重定义LED的物理映射(HAL…

MirrorLayer可以正常触摸屏幕原理分析

背景&#xff1a; 上次blog分享了给学员朋友们布置的作业&#xff0c;今天来进行简单的揭秘。 问题&#xff1a; 在多屏互动时候有一个屏幕的画面是一个MirrorLayer&#xff0c;另一个屏幕画面是真实的&#xff0c;即2个屏幕上有一个是MirrorLayer&#xff0c;这个时候疑问就…

算法篇之二分

二分算法简介 特点 最简单的一种算法&#xff0c;也是最恶心&#xff0c;细节最多&#xff0c;最容易写出死循环的算法时间复杂度O(logN) 如何学习 明白其中的算法原理&#xff0c;二分并不是只有数组有序的的时候使用&#xff0c;而是看是否具有二段性。模板 朴素的二分模…

算法面试八股文『 基础知识篇 』

博客介绍 近期在准备算法面试&#xff0c;网上信息杂乱不规整&#xff0c;出于强迫症就自己整理了算法面试常出现的考题。独乐乐不如众乐乐&#xff0c;与其奖励自己&#xff0c;不如大家一起嗨。以下整理的内容可能有不足之处&#xff0c;欢迎大佬一起讨论。 PS&#xff1a;…

失物招领|基于Springboot的校园失物招领系统设计与实现(源码+数据库+文档)

校园失物招领系统目录 目录 基于Springboot的校园失物招领系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、 管理员功能实现 (1) 失物招领管理 (2) 寻物启事管理 (3) 公告管理 (4) 公告类型管理 2、用户功能实现 (1) 失物招领 (2) 寻物启事 (3) 公告 …

2024 美国大学生数学建模竞赛 美赛(C题)网球比赛趋势问题 国际大学生数学建模竞赛| 建模秘籍文章代码思路大全

铛铛&#xff01;小秘籍来咯&#xff01; 小秘籍希望大家都能轻松建模呀&#xff0c;华数杯也会持续给大家放送思路滴~ 抓紧小秘籍&#xff0c;我们出发吧~ 完整内容可以在文章末尾领取&#xff01; 问题1 • 开发一个模型&#xff0c;捕捉到比赛进行时点的流动&#xff0c;…

(2)(2.11) RFD900

文章目录 前言 1 概述 2 主要功能 3 状态LED指示灯 4 接口 5 使用Mission Planner进行配置 6 支持不同国家/地区 7 讨论论坛 前言 RFD900 无线电调制解调器是一款高功率 900Mhz ISM 波段无线电调制解调器&#xff0c;设计用于远距离串行通信。据报道&#xff0c;其通信…

2024美国大学生数学建模美赛选题建议+初步分析

总的来说&#xff0c;去年算是美赛环境题元年&#xff0c;去年的开放度是较高的&#xff0c;今年每种赛题类型相对而言平均了起来 提示&#xff1a;DS C君认为的难度&#xff1a;E<BCF<AD&#xff0c;开放度&#xff1a;DBCE<A<F。 以下为A-F题选题建议及初步分析…

C++(17.5)——list模拟实现扩展

在上篇文章中&#xff0c;实现了的大部分功能以及部分迭代器。本片文章将对剩下的功能进行补充。 1. const迭代器&#xff1a; 对于上篇文章中实现的迭代器只能使用于非类型的对象。对于类型的遍历&#xff0c;则需要额外编写类型的迭代器。例如对于下面的场景&#xff1a; …

grafana安装DevOpsProdigy KubeGraf 1.5.2

安装DevOpsProdigy KubeGraf需要安装kube-state-metrics 官方地址&#xff1a;https://github.com/kubernetes/kube-state-metrics/tree/release-2.10/examples/standard 查看k8s版本和kube-state-metrics对应版本&#xff1a; [rootmaster1 kube-state-metrics]# ll 总用量 …

25考研|660/880/1000/1800全年带刷计划

作为一个参加过两次研究生考试的老学姐&#xff0c;我觉得考研数学的难度完全取决于你自己 我自己就是一个很好的例子 21年数学题目是公认的简单&#xff0c;那一年考130的很多&#xff0c;但是我那一年只考了87分。但是22年又都说是有史以来最难的一年&#xff0c;和20年的难度…

华擎B660 主板 怎么设置打开来电自启功能?

环境&#xff1a; 华擎B660 钢铁传奇 1700 : Intel B660 问题描述&#xff1a; 华擎B660 主板 怎么设置打开来电自启功能&#xff1f; 解决方案&#xff1a; 1.前往-高级- 芯片组配置 2.往下划找到交流 /电源断电恢复 选择电源故障后的电源状态。如果选择 [关机]&#x…

《PCI Express体系结构导读》随记 —— 第II篇 第4章 PCIe总线概述(4)

接前一篇文章&#xff1a;《PCI Express体系结构导读》随记 —— 第II篇 第4章 PCIe总线概述&#xff08;3&#xff09; 4.1.2 PCIe总线使用的信号 PCIe设备使用两种电源信号供电&#xff0c;分别是Vcc与Vaux&#xff0c;其额定电压为3.3V。其中Vcc为主电源&#xff0c;PCIe设备…

免费分享一套SpringBoot+Vue药店(药房)管理系统,帅呆了~~

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的SpringBootVue药店(药房)管理系统 &#xff0c;分享下哈。 项目视频演示 【免费】SpringBootVue药店(药房)管理系统 Java毕业设计_哔哩哔哩_bilibili【免费】SpringBootVue药店(药房)管理系统 Java毕业设计…

flutter实战之美化 container

我们来看一个代码 Column(children: [...transaction.map((e) > Card(child:Row(children: [Container(child: Text(e.amout.toString()),),Column(children: [Text(e.title),Text(e.date.toString()),],)],),)).toList()],) 看看效果 感觉很不好 我们要去美化一下contai…

[晓理紫]每日论文分享(有中文摘要,源码或项目地址)

专属领域论文订阅 关注{晓理紫|小李子}&#xff0c;每日更新论文&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持 如果你感觉对你有所帮助&#xff0c;请关注我&#xff0c;每日准时为你推送最新论文。 为了答谢各位网友的支持&#xff0c;从今日起…

pytorch_car_caring 排坑记录

pytorch_car_caring 排坑记录 任务踩坑回顾简单环境问题代码版本问题症状描述解决方法 cuda问题&#xff08;异步问题&#xff09;症状描述解决方法 任务 因为之前那个MPC代码跑出来的效果不理想&#xff0c;看了一天代码&#xff0c;大概看明白了&#xff0c;但要做改进还要有…

力扣hot100 对称二叉树 递归

Problem: 101. 对称二叉树 文章目录 思路Code 思路 &#x1f468;‍&#x1f3eb; 参考 Code 时间复杂度: O ( n ) O(n) O(n) 空间复杂度: O ( n ) O(n) O(n) /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* …

Pytorch从零开始实战18

Pytorch从零开始实战——人脸图像生成 本系列来源于365天深度学习训练营 原作者K同学 文章目录 Pytorch从零开始实战——人脸图像生成环境准备模型定义开始训练可视化总结 环境准备 本文基于Jupyter notebook&#xff0c;使用Python3.8&#xff0c;Pytorch2.0.1cu118&#…