二分搜索算法的介绍和使用

C++——《算法分析》实验壹——二分搜索算法 实验目的: 1.理解分治算法的概念和基本要素; 2.理解递归的概念; 3.掌握设计有效算法的分治策略; 4.通过二分搜索技术学习分治策略设计技巧; 实验原理 二分搜索算法也称为折半查找法,它充分利用了元素间的次序关系,采用分治策略,可在最坏的情况下用O(log n)完成搜索任务。 实验内容: 1.使用二分搜索算法查找任意N个有序数列中的指定元素。 2.通过上机实验进行算法实现。 3.保存和打印出程序的运行结果,并结合程序进行分析,上交实验报告。 4.至少使用两种方法进行编程。 实验代码 #include & 阅读详情

一、什么是二分搜索

二分搜索(Binary Search)是一种在有序数组/区间中查找目标值的位置的算法。
核心思想:每次把搜索范围缩小一半,从而快速定位数据。范围从 n 缩小到 n/2 → n/4 → n/8…

时间复杂度就是:

O(log n)

二、二分搜索的适用条件

必须满足两个条件:

  1. 数据有序(升序或降序)
  2. 可以通过下标随机访问(数组、vector 等)

不适用于链表(随机访问 O(n))

三、二分搜索的工作流程

示例:在数组中查找 target = 9
数组(升序):

索引: 0  1  2  3  4  5   6
数据: 1  3  5  7  9  11  15

初始区间:

l = 0
r = 6

第 1 次查找

区间: [0........................................6]
数据:  1  3  5  7  9  11  15
             ^ mid = 3  (值 = 7)

判断:

nums[mid] = 7 < 9
→ 目标在右侧
→ l = mid + 1 = 4

第 2 次查找

区间: [4....................6]
数据:  1  3  5  7  9  11  15
                    ^ mid = 5 (值 = 11)

判断:

nums[mid] = 11 > 9
→ 目标在左侧
→ r = mid - 1 = 4

第 3 次查找

区间: [4]
数据:  1  3  5  7  9  11  15
                ^ mid = 4 (值 = 9)

判断:

nums[mid] == target → 找到目标

整个过程的如下展示:

Step 1:
[1 3 5 7 9 11 15]
 l           m     r
 0           3     6

Step 2:
[1 3 5 7 9 11 15]
         l     m   r
         4     5   6

Step 3:
[1 3 5 7 9 11 15]
             l/m/r
             4

更形象的“半区排除图”

开始:
[ 1  3  5  7 | 9  11  15 ]
               ↑7<9 → 左半区丢弃

继续:
[ 9 | 11  15 ]
      ↑11>9 → 右侧丢弃

最终:
[ 9 ]
  ↑ 找到!

四、二分搜索常见错误

中间点写成 (l + r) / 2 可能溢出
建议:

mid = l + (r - l) / 2;

while 条件写成 < 或 <= 搞混
闭区间写法必须:

while (l <= r)

开区间写法:

while (l < r)

不要死循环
如:

mid = (l + r) / 2;
// 然后没有改变 l 或 r

一定要注意每次都要缩小范围。

五、二分搜索的代码模板(升序)

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

// 标准二分:查找 target
int binarySearch(const vector<int>& nums, int target) {
    int l = 0, r = nums.size() - 1;

    while (l <= r) {
        int mid = l + (r - l) / 2;

        if (nums[mid] == target)
            return mid;
        else if (nums[mid] < target)
            l = mid + 1;
        else
            r = mid - 1;
    }
    return -1;
}

int main() {
    vector<int> nums = {1, 3, 5, 7, 9, 11};

    cout << binarySearch(nums, 7) << endl; // 输出 3
    
    return 0;
}

为什么不能用 mid = (l+r)/2?
因为会发生「整数溢出」(overflow)
假设:

int l = 1_000_000_000;
int r = 2_000_000_000;

两者都在 int 可表示范围内,但你求 mid 时:

int mid = (l + r) / 2;  // 可能溢出

l + r = 3_000_000_000,已经超过 int 最大值(2_147_483_647)
产生溢出 → mid 变成负数或奇怪值,程序会直接二分错位甚至死循环。

所以才有了 官方推荐写法:

int mid = l + (r - l) / 2;

这样 r - l 永远不会超出范围(最大约 2e9),避免溢出。

图示解释(直观)
假设区间 [l, r] = [10, 20]
错误写法:

 mid = (10 + 20) / 2 = 15   // ✔ 正常

但当边界巨大:

 l → 非常大
 r → 非常大
 l + r → 超过 int 上限 → ❌ 溢出

正确写法:

 mid = l + (r - l) / 2

因为 (r - l) 很小,所以不会超出范围

结论:不能使用 (l + r) / 2 的主要原因是:当 l 和 r 足够大时,l + r 可能产生整数溢出,导致 mid 计算错误。而 l + (r - l) / 2 不会溢出,因此是安全写法。

六、查找第一个 >= target

在有序数组中查找:

第一个 >= target 的位置

假设:

数组: [1, 3, 5, 7, 9, 11, 15]
target = 8

正确答案应该是元素 9(index = 4),因为它是第一个 ≥ 8 的数字。

使用的二分区间写法(典型的 lower_bound 写法)

l = 0
r = n   // r 是开区间,不可取
while (l < r)

mid = (l + r) / 2
如果 nums[mid] >= target → 可能是答案 → 缩 r
否则 → mid 太小 → 缩 l

图形演示过程:

Step 1:
[1 3 5 7 9 11 15]
 l           m      r
 0           3      7
(7 < 8 → 左半废)

Step 2:
[1 3 5 7 9 11 15]
             l   m   r
             4   5   7
(11 >= 8 → 右半废)

Step 3:
[1 3 5 7 9 11 15]
             l/m r
             4   5
(9 >= 8 → 右半废)

Step 4:
[1 3 5 7 9 11 15]
             l=r=4

C++ 版本(对应这个图示)

int lowerBound(const vector<int>& nums, int target) {
    int l = 0, r = nums.size(); // 开区间

    while (l < r) {
        int mid = l + (r - l) / 2;

        if (nums[mid] >= target)
            r = mid;       // mid 可能是答案
        else
            l = mid + 1;   // mid 太小
    }

    return l;  // 第一个 >= target 的位置
}

七、查找最后一个 <= target

使用的二分模板(闭区间版本)
要找 “最后一个 ≤ target”,一般用 闭区间 [l, r] 写法:

while (l <= r):
    mid = ...
    if nums[mid] <= target:
         ans = mid      // 可能是答案
         l = mid + 1    // 尝试往右找更大的
    else:
         r = mid - 1

图形演示过程:

Step 1:
[1 3 5 7 9 11 15]
 l       m       r
 0       3       6
(7 <= 8 → 候选,往右找)


Step 2:
[1 3 5 7 9 11 15]
         l   m   r
         4   5   6
(11 > 8 → 往左)


Step 3:
[1 3 5 7 9 11 15]
         l/m r
         4   4
(9 > 8 → 往左)


Step 4:
[1 3 5 7 9 11 15]
         r   l
         3   4
结束 → r=3

完整 C++ 代码(对应图示)

int lastLessEqual(const vector<int>& nums, int target) {
    int l = 0, r = nums.size() - 1;
    int ans = -1;

    while (l <= r) {
        int mid = l + (r - l) / 2;

        if (nums[mid] <= target) {
            ans = mid;     // 记录候选
            l = mid + 1;   // 去右边找更大的
        } else {
            r = mid - 1;
        }
    }
    return ans; // 返回最后一次记录的位置
}
算法学习1——二分搜索 Python提升——二分搜索算法,使用Python自带的伪随机数生成器random,生成长度为10的随机列表,通过二分搜索算法找到某元素在列表中的位置。 阅读详情

相关推荐

二分搜索算法通解框架

文章介绍了二分搜索最常见的几个场景的使用:寻找一个数、寻找左侧边界以及寻找右侧边界。阅读本文只需读者了解二分搜索的使用限制和基本原理即可。

东 656

【算法】二分搜索

本文对二分搜索算法进行了详细地介绍,包括概述、代码实现和应用。

代码星辰的博客 5711

c语言实现二分搜索算法

二分搜索针对有序的数组,每次和中间元素比较,如果相等则直接返回,如果不相等则搜索范围可以减半。二分法可以将复杂度从 Ο(n) 降到 Ο(log n)。 本来以为二分法很简单,半分钟搞定,但写起来尼玛才发现不是这里有点问题,就是那里有问题。 针对整数的二分搜索 直接上代码: int binary_search(int data[], int n, int x){ if(n 0 || x d

zdarks的专栏 6777

详解二分搜索算法

我周围的人几乎都认为二分查找很简单,但事实真的如此吗?二分查找真的很简单吗?并不简单。看看 Knuth 大佬(发明 KMP 算法的那位)怎么说的: Although the basic idea of binary search is comparatively straightforward, the details can be surprisingly tricky… 这句话可以这样理解:思路很简单,细节是魔鬼。 本文就来探究几个最常用的二分查找场景:寻找一个数、寻找左侧边界、寻找右侧边界。 而且,我

qq_43460883的博客 1977

基于STM32F407与AD9910/AD9959的高频可调DDS信号源设计与实战

本文详细介绍了基于STM32F407微控制器与AD9910/AD9959高性能DDS芯片的高频可调信号源设计与实现。文章从DDS原理入手,阐述了双芯片方案的优势,并重点分享了高频电路设计中的电源、PCB布局布线等关键硬件设计技巧与避坑指南。同时,提供了通过SPI配置DDS芯片及利用Matlab生成任意波形的软件驱动方法,旨在帮助开发者打造一个覆盖10Hz至4200MHz的实用信号发生器。

weixin_36184718的博客 120

ROS2 Humble + TurtleBot4仿真环境搭建与避坑实战

本文详细介绍了ROS2 Humble与TurtleBot4仿真环境的搭建与避坑实战,包括环境配置、依赖安装、仿真调试和性能优化等关键步骤。通过保姆级教程和实用技巧,帮助开发者快速搭建稳定的机器人仿真环境,提升开发效率。特别推荐使用Ubuntu 22.04原生系统以避免常见问题。

weixin_30897233的博客 398

二分搜索算法详解(Binary Search)

二分搜索(Binary Search) 如何确定一个元素在数组中的位置?(假设数组里面全都是整数) 如果是无序数组,从第0个位置开始遍历搜索,平均时间复杂度:O(n) 如果是有序数组,可以使用二分搜索,最坏时间复杂度为O(logn) (一)、二分搜索 — 思路 假设在[begin,end)范围内搜索某个元素 v,mid == (begin + end)/ 2 ①、如果v < m,去[begin , mid)范围内二分搜索 ②、如果v > m,去[mid + 1, end)范围内二分搜索 ③、如果v == m

派拉斯兔子的博客 4万+

2025年北京市职工职业技能大赛第六届信息通信行业网络安全技能大赛复赛CTF部分WP-哥斯拉流量分析

题目没有任何提示,附件gzl.pcap解题哥斯拉流量300多KB包很多,没啥经验只能挨个看回来之后又狠狠得撸了一把哥斯拉流量分析我这里用的是哥斯拉4.0.1测试链接这里发了两个包,我们进行分析。

深耕网络安全领域,聚焦护网行动(HW)、渗透测试、等级保护(等保)、CTF 竞赛四大核心方向,提供技术干货、实战经验与行业洞察。 1810

二分查找(精确查找、范围搜索)

二分查找法,也称为二分搜索法或折半查找法,是一种在有序数组中查找特定元素的搜索算法。其基本思想是,通过不断将待查找的区间分成两半,并与待查找的元素进行比较,根据比较结果调整查找区间,直到找到元素或区间被缩小至0为止。时间复杂度为O(log n)使用条件:二分查找要求数组必须是有序的,无论是升序还是降序。如果数组无序,则需要先进行排序操作。易错点:while循环过程中,left与right的关系容易错乱;left与right指针的移动容易错。

weixin_44248258的博客 2468

UE4入门实例17(Unreal制作卡通Post Process材质球)

效果展示 #1 创建Post Porcess材质球 #2 编写Shader功能 #3 设置场景区域内风格化渲染 #1 创建Post Porcess材质球 #2 编写Shader功能 创建基础效果 移除现有通道渲染 设置视图渲染范围 #3 设置场景区域内风格化渲染 #4 加群下载Shader源码:284105567 ...

Unity3d 攻城师一枚 1343

保姆级教程:用MATLAB复现格拉斯哥大学FMCW雷达数据集多普勒谱(附完整代码与避坑指南)

本文提供了一份详细的MATLAB教程,指导如何复现格拉斯哥大学FMCW雷达数据集的多普勒谱分析。从环境准备、数据获取到距离压缩、MTI滤波、时频分析(STFT)以及结果后处理,涵盖了完整流程,并附有优化代码和避坑指南,特别适合雷达信号处理研究者和工程师。

weixin_28720767的博客 114

二分查找(折半查找)

二分查找是一种算法,其输入是一个有序的元素列表(必须是有序的),如果查找的元素包含在列表中,二分查找返回其位置,否则返回NULL 比如说有一个1-100的数字,我随机的选择其中一个数字(假设为60),你需要以最少的次数猜到我所选择的数字,每次猜测后,我会告诉你大了,小了,对了。 假设你第一次从1开始猜,小了 第二次:2 小了 第三次:3 小了 …… 第五十九次:59小了 ...

zmeilin的博客 15万+

论文复现《基于最大李雅普诺夫指数的电力系统暂态电压稳定评估方案》

电力系统暂态电压稳定评估方案 摘要 本研究提出了一种基于最大李雅普诺夫指数的电力系统暂态电压稳定评估方法。通过分析相空间中相邻轨迹的收敛或发散特性,该方法能够提前判别系统稳定性。论文首先阐述了暂态电压稳定机理,详细介绍了最大李雅普诺夫指数的计算方法。针对IEEE-39节点系统,建立了仿真模型并获取不同故障场景下的数据。研究开发了完整的评估程序,包括数据预处理、相空间重构、指数计算等模块,并通过与时域仿真结果的对比验证了方法的准确性。实验结果表明,该方法能够快速有效地评估电力系统的暂态电压稳定性,为系统安全运

max500600的博客 184

重拾算法之路——二分搜索

重拾算法之路——二分搜索

继续激情,继续奋斗。 1186

AI在保险产品定价优化中的创新应用

在当今保险市场中,准确合理的产品定价是保险公司实现可持续发展的关键因素之一。传统的保险产品定价主要基于经验数据和精算模型,但这种方式往往存在数据处理效率低、对复杂风险因素考虑不足等问题。本文的目的在于深入探讨AI技术如何在保险产品定价中进行创新应用,以提高定价的准确性、效率和灵活性,更好地满足市场需求和客户个性化需求。本文的范围涵盖了AI技术在保险产品定价各个环节的应用,包括风险评估、费率计算、产品设计等方面。同时,还会涉及到相关的核心算法、数学模型以及实际应用案例等内容。

欢迎来到我的优快云空间!这里聚焦AI大模型应用实战,分享前沿技术、实战案例与开发经验。 982

Python爬虫技术:使用Playwright和Twitter API v2高效获取Twitter/X数据完全教程

遵守规则:始终遵循Twitter的使用条款和速率限制错误处理:实现完善的错误处理和重试机制数据质量:进行数据清洗和验证性能优化:使用异步处理和合理的延迟设置可维护性:模块化代码,便于维护和扩展。

2201_76125261的博客 671

二分搜索算法框架解析

文章目录一、寻找一个数(基本的二分搜索)二、寻找左侧边界的二分搜索三、寻找右侧边界的二分查找总结 一、寻找一个数(基本的二分搜索) 这个场景是最简单的,可能也是大家最熟悉的,即搜索一个数,如果存在,返回其索引,否则返回 -1。 int binarySearch(int[] nums, int target) { int left = 0; int right = nums.length - 1; // 注意 while(left <= right) { in

c630843901的博客 282

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

[FreeCodeCamp笔记] Python 数据结构和算法1 二分搜索 Binary Search

我以前学过数据结构和算法(data structure and algorithms. 现在普遍简称DSA),当时用的Robert Sedgewick的coursera课程。这位大神写的《算法(第四版)》,是算法的经典教材,可惜这本书900页,我直接被吓跑了。而coursera课程用的是java,我又不会java,所以课后习题做的异常艰苦。 这几天,我又想学一下数据结构和算法,但是我决定用python学。其实我也会c++和c#,但是python显然是最简单易用的语言,使用python可以节省很多时间。于是,

juwikuang的专栏 2735

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

C++——《算法分析与设计》实验报告——二分搜索算法

实验名称: 二分搜索算法 实验地点: 实验目的: 理解分治算法的概念和基本要素; 理解递归的概念; 掌握设计有效算法的分治策略; 通过二分搜索技术学习分治策略设计技巧; 实验原理 二分搜索算法也称为折半查找法,它充分利用了元素间的次序关系,采用分治策略,可在最坏的情况下用O(log n)完...

无限迭代中...... 2756

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

二分搜索算法--《算法分析与设计》实 验 报 告(一)

一、实验目的 1.理解分治算法的概念和基本要素; 2.理解递归的概念; 3.掌握设计有效算法的分治策略; 4.通过二分搜索技术学习分治策略设计技巧; 二、实验内容 实验内容: 1.使用二分搜索算法查找任意N个有序数列中的指定元素。 2.通过上机实验进行算法实现。 3.保存和打印出程序的运行结果,并结合程序进行分析,上交实验报告。 至少使用两种方法进行编程。 三、源程序 import jav...

qq_44890213的博客 2713

二分搜索算法(折半查找)实现

因为刚开始first是0,last是10,(0+10)/2=5,所以它先搜的是57,它拿57作为入口,如果搜索的元素的值==57,就搜到了,就走人了。如果搜索的元素的值小于25,first和last都跑到0号位置了,就和0号位置的12比较,如果相等就找到了,如果不相等就是找不到。如果比82大,first跑到9号位置,(9+10)/2=9,可以和96比较,比96小就没了,比96大,还可以和100比较。如果搜索的元素的值大于34,first=3,(3+4)/2=3,和39比较,线性搜索的时间复杂度是O(n)

ljy的博客 860

Java-自带的二分搜索和排序

java的Arrays 类中已经写好了排序和二分搜索 package com.company; import java.util.Arrays; public class ArrayTest { public static void main(String[] args){ int[] a = {6,17,92,32,58,22,84,66,36,33}; //测试数据...

BLOG OF PETERMAOSX. 1095

基础搜索算法篇---二分搜索

基础算法--二分查找

qq_33783517的博客 1337

【算法设计】递归与分治算法设计——二分搜索、假币识别问题(C++实现)

算法分析与设计——二分搜索和假币识别问题:设a[0:n-1]是已排好序的数组。试改写二分搜索算法,使得当搜索元素x不在数组a中时,返回小于的最大元素的位置i和大于x的最小元素的位置j当搜索元素x在数组a中时,返回x在数组中的位置,此时i和j相同。一个袋子里有n个硬币,其中一枚是假币,假币和真币外观一模一样,仅凭肉眼无法区分,但是已知假币比真币轻一些。试设计识别假币的分治算法算法思想和解题思路 先将有序数组分成两部分,中间位置mid为基准值 若该值等于目标值key,则直接返回 若该值大于目标值,则在左半部

努力让自己的能力配得上梦想. 1034

python改写二分搜索算法_二分搜索算法模板python实现

二分搜索的算法理解起来比较简单但是边界条件容易出错,比如 循环结束条件中 left 和 right 的关系,更新 left 和 right 位置时要不要加 1 减 1。模板def binary_search(list, target):low = 0high = len(list) - 1while low <= high:mid = (low + high) // 2if list[mid...

weixin_39953845的博客 267

改写二分搜索算法

一、实践题目 改写二分搜索算法 二、问题描述 设a[0:n-1]是已排好序的数组,请改写二分搜索算法,使得当x不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j。当搜索元素在数组中时,i和j相同,均为x在数组中的位置。 输入格式: 输入有两行: 第一行是n值和x值; 第二行是n个不相同的整数组成的非降序序列,每个整数之间以空格分隔。 输出格式: 输出小于x...

weixin_30412167的博客 1217
上一篇: 排序算法:插入排序算法
下一篇: 排序算法:希尔排序算法
TechNomad
博客等级 码龄2年 787粉丝 183原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值