二分查找的各种应用详解(C++)

2023-11-05

基本概念

  1. Binary Search

    二分查找也称折半查找,它是一种效率较高的查找方法;使用二分查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。

  2. 基本原理

    ①.查找:因为序列已经单调且有序排列,从中间位置开始比较,一次可以排除一半的数据,不断缩小查找范围;

    ②.终止条件:找到了目标值,或者左右边界已经构不成有效区间;

    ③.左右边界:理想情况下右边界不断缩小以逼近目标位置,左边界不断增大以逼近目标位置。

查找等于 key 的元素位置

// target == key
// 找到目标值或者构不成有效区间就返回
int binarySearch( vector<int>& nums, int target)
{
    int letft = 0;
    int right = nums.size()-1;//查找区间范围 [left,right]
    whiel(left <= right)// 结束条件 left = right+1 时,[right+1,right] 构不成合理区间范围
    {
        int mid = left + (right - left )/2;//防止相加后超 int 范围
        if( nums[mid] == target )//找到了
        {
            return mid;
        }
        else if( nums[mid] < target )// mid 值小,需要增加左边界,且 mid 位置已排除
        {
            left = mid +1;
        }
        else if( nums[mid] > target )// mid 值大,需要缩小右边界,且 mid 位置已排除
        {
            right = mid -1;
        }
        return -1;//没有找到目标值
    }
}

查找第一个大于 key 的元素位置

// target > key
// 不断缩小右边界使其不断逼近目标位置,当最后一下缩小位置后恰好不满足条件,因此返回 right+1 ,即 left
int binarySearch( vector<int>& nums, int target)
{
    int letft = 0;
    int right = nums.size()-1;//查找区间范围 [left,right]
    whiel(left <= right)// 结束条件 left = right+1 时,[right+1,right] 构不成合理区间范围
    {
        int mid = left + (right - left )/2;//防止相加后超 int 范围
        if( nums[mid] <= target )// mid 值小,需要增加左边界,且 mid 位置已排除
        {
            left = mid +1;
        }
        else if( nums[mid] > target )// 找到了一个符合条件的值,缩小右边界,看有没更符合条件的值
        {
            right = mid -1;
        }
    }
    return left <= nums.size()-1 ? left :-1;//判断是否出界
}

查找第一个大于或者等于 key 的元素位置

// target >= key
// 不断缩小右边界使其不断逼近目标位置,当最后一下缩小位置后恰好不满足条件,因此返回 right+1 ,即 left
int binarySearch( vector<int>& nums, int target)
{
    int letft = 0;
    int right = nums.size()-1;//查找区间范围 [left,right]
    whiel(left <= right)// 结束条件 left = right+1 时,[right+1,right] 构不成合理区间范围
    {
         int mid = left + (right - left )/2;//防止相加后超 int 范围
         if( nums[mid] >= target )//找到了一个符合条件的值,缩小右边界,看有没更符合条件的值
         {
             right = mid -1;
         }
        else  if( nums[mid] < target )// mid 值小,需要增加左边界,且 mid 位置已排除
        {
            left = mid +1;
        }
    }
    return left <= nums.size()-1 ? left :-1;//判断是否出界
}

查找第一个等于 key 的元素位置

// target == key
// 不断缩小右边界使其不断逼近目标位置,当最后一下缩小位置后恰好不满足条件,因此返回 right+1 ,即 left
int binarySearch( vector<int>& nums, int target)
{
    int letft = 0;
    int right = nums.size()-1;//查找区间范围 [left,right]
    whiel(left <= right)// 结束条件 left = right+1 时,[right+1,right] 构不成合理区间范围
    {
        int mid = left + (right - left )/2;//防止相加后超 int 范围
        if( nums[mid] > target )// mid 值大,需要缩小右边界,且 mid 位置已排除
        {
             right = mid -1;
        }
        else if( nums[mid] < target )// mid 值小,需要增加左边界,且 mid 位置已排除
        {
            left = mid +1;
        }
        if( nums[mid] == target )//找到了一个符合条件的值,缩小右边界,看有没更符合条件的值
        {
             right = mid -1;
        }
        return left <= nums.size()-1 && nums[left] == target ? left :-1;//判断是否出界
    }
}

查找最后一个小于 key 的元素位置

// target < key
// 不断增大左边界使其不断逼近目标位置,当最后一下增加位置后恰好不满足条件,因此返回 left-1 ,即 right
int binarySearch( vector<int>& nums, int target)
{
    int letft = 0;
    int right = nums.size()-1;//查找区间范围 [left,right]
    whiel(left <= right)// 结束条件 left = right+1 时,[right+1,right] 构不成合理区间范围
    {
        if( nums[mid] >= target )// mid 值大,需要缩小右边界,且 mid 位置已排除
        {
            right = mid -1;
        }
        else if( nums[mid] < target )//找到了一个符合条件的值,增加左边界,看有没更符合条件的值
        {
            left = mid +1;
        }
    }
    return right >= 0 ? right :-1;//判断是否出界
}

查找最后一个小于或者等于 key 的元素位置

// target <= key
// 不断增大左边界使其不断逼近目标位置,当最后一下增加位置后恰好不满足条件,因此返回 left-1 ,即 right
int binarySearch( vector<int>& nums, int target)
{
    int letft = 0;
    int right = nums.size()-1;//查找区间范围 [left,right]
    whiel(left <= right)// 结束条件 left = right+1 时,[right+1,right] 构不成合理区间范围
    {
        if( nums[mid] > target )// mid 值大,需要缩小右边界,且 mid 位置已排除
        {
            right = mid -1;
        }
        else if( nums[mid] <= target )//找到了一个符合条件的值,增加左边界,看有没更符合条件的值
        {
            left = mid +1;
        }
    }
    return right >= 0 ? right :-1;//判断是否出界    
}

查找最后一个等于 key 的元素位置

// target == key
// 不断增大左边界使其不断逼近目标位置,当最后一下增加位置后恰好不满足条件,因此返回 left-1 ,即 right
int binarySearch( vector<int>& nums, int target)
{
    int letft = 0;
    int right = nums.size()-1;//查找区间范围 [left,right]
    whiel(left <= right)// 结束条件 left = right+1 时,[right+1,right] 构不成合理区间范围
    {
        if( nums[mid] > target )// mid 值大,需要缩小右边界,且 mid 位置已排除
        {
            right = mid -1;
        }
        else if( nums[mid] == target )//找到了一个符合条件的值,增加左边界,看有没更符合条件的值
        {
            left = mid +1;
        }
        else if( nums[mid] < target )// mid 值小,需要增加左边界,且 mid 位置已排除
        {
            left = mid +1;
        }
    }
    return right >= 0 && nums[right] == target ? right :-1;//判断是否出界    
}

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

二分查找的各种应用详解(C++) 的相关文章

  • VLC 媒体播放器有 C# 界面吗? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否可以使用 C 控制台应用程序中的包装器从 VLC 播放中当前播放的文件中读取曲目统计信息 时间 标
  • 在 C 语言中,为什么数组的地址等于它的值?

    在下面的代码中 指针值和指针地址与预期不同 但数组值和地址则不然 怎么会这样 Output my array 0022FF00 my array 0022FF00 pointer to array 0022FF00 pointer to a
  • 在 C++ 代码中转换字符串

    我正在学习 C 并开发一个项目来练习 但现在我想在代码中转换一个变量 字符串 就像这样 用户有一个包含 C 代码的文件 但我希望我的程序读取该文件并插入将其写入代码中 如下所示 include
  • C# 中一次性对象克隆会导致内存泄漏吗?

    检查这个代码 class someclass IDisposable private Bitmap imageObject public void ImageCrop int X int Y int W int H imageObject
  • 使用 C# 和 ASP.NET 在电子邮件附件中发送 SQL 报告

    我正在尝试使用 ASP NET 和 C 从 sql reportserver 2008 作为电子邮件附件发送报告 到目前为止我学会了如何获取 PDF 格式的报告 http weblogs asp net srkirkland archive
  • 用于在标头更改时重新编译的简单 C 项目的示例 makefile

    有谁有完整的 makefile 可以执行以下操作 如果 HEADER 文件发生更改 则重建项目 cpp 文件在 makefile 中列出 头文件未在 makefile 中列出 头文件允许与 cpp 文件具有不同的名称 部分cpp文件没有头文
  • if constexpr 中的 not-constexpr 变量 – clang 与 GCC

    struct A constexpr operator bool const return true int main auto f auto v if constexpr v A a f a clang 6 接受该代码 GCC 8 拒绝它
  • LinkLabel 无下划线 - Compact Framework

    我正在使用 Microsoft Compact Framework 开发 Windows CE 应用程序 我必须使用 LinkLabel 它必须是白色且没有下划线 因此 在设计器中 我将字体颜色修改为白色 并在字体对话框中取消选中 下划线
  • 如何在 Javascript 中连接 C# ActiveX 事件处理程序

    我尝试使用几个代码片段将 ActiveX 对象与 Javascript 事件处理程序挂钩 我无法确定为什么事件处理程序没有被调用 带有项目的 Github 存储库 https github com JesseKPhillips Csharp
  • Unity c# 四元数:将 y 轴与 z 轴交换

    我需要旋转一个对象以相对于现实世界进行精确旋转 因此调用Input gyro attitude返回表示设备位置的四元数 另一方面 这迫使我根据这个四元数作为默认旋转来计算每个旋转 将某些对象设置为朝上的简单方法如下 Vector3 up I
  • 如何在多线程应用程序中安全地填充数据并 Refresh() DataGridView?

    我的应用程序有一个 DataGridView 对象和一个 MousePos 类型的列表 MousePos 是一个自定义类 它保存鼠标 X Y 坐标 类型为 Point 和该位置的运行计数 我有一个线程 System Timers Timer
  • MySQL 连接器 C++ 64 位在 Visual Studio 2012 中从源代码构建

    我正在尝试建立mySQL 连接器 C 从源头在视觉工作室2012为了64 bit建筑学 我知道这取决于一些boost头文件和C 连接器 跑步CMake生成一个项目文件 但该项目文件无法编译 因为有一大堆非常令人困惑的错误 这些错误可能与包含
  • SQLAPI++ 的免费替代品? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有任何免费 也许是开源 的替代品SQLAPI http www sqlapi com 这个库看起来
  • 以编程方式创建 Blob 存储容器

    我有一个要求 即在创建公司时 在我的 storageaccount 中创建关联的 blob 存储容器 并将容器名称设置为传入的字符串变量 我已尝试以下操作 public void AddCompanyStorage string subDo
  • 使用 gcc 时在头文件中查找定义的好方法是什么?

    在使用 gcc 时 有人有推荐的方法在头文件中查找定义吗 使用 MSVC 时 我只需右键单击并选择 转到定义 这非常好 我使用过 netbeans gcc 它确实有代码帮助 包括到定义的超链接 所以这是一种选择 但是 我想知道是否有任何其他
  • C++ 指针引用混淆

    struct leaf int data leaf l leaf r struct leaf p void tree findparent int n int found leaf parent 这是 BST 的一段代码 我想问一下 为什么
  • 如何编写一个接受 int 或 float 的 C 函数?

    我想用 C 语言创建一个扩展 Python 的函数 该函数可以接受 float 或 int 类型的输入 所以基本上 我想要f 5 and f 5 5 成为可接受的输入 我认为我不能使用if PyArg ParseTuple args i v
  • 如何获取带有某个属性注释的所有属性?

    我刚刚从 Roslyn 开始 我想找到所有用属性名称 OneToOne 注释的属性 我启动了 SyntaxVisualizer 并能够获取对该节点的引用 但我想知道是否有更简单的方法来实现此目的 这就是我所拥有的 var prop docu
  • Streamwriter 覆盖 txt 文件中的文本

    有没有什么方法可以重新打开流写入器而不创建新的写入对象 因为此时 当调用 WriteOdd 时 streamwriter 正在覆盖在它之前调用的 WriteEven public void WriteEven StreamWriter wr
  • .Net Reactive Extensions Framework (Rx) 是否考虑拓扑顺序?

    Net 反应式扩展框架是否按拓扑顺序传播通知以最大限度地减少更新量 就像 Scala Rx 所做的那样 Net 反应式扩展 Rx 是否可以 https github com lihaoyi scala rx wiki How it Work

随机推荐

  • Σ-Δ ADC的高精度数模转化,是如何实现的?

    以前接触过 ADC24位采样芯片 一直对其原理没有搞清楚 最近看到有对其原理讲解的文章 因此收集下来作为参考 我们在了解Delta Sigma ADC原理之前 先明确几个概念 1 量化噪声 下图中 蓝色斜线是连续的模拟信号 阶梯状波形是经过
  • Flask学习笔记_异步CMS(五)

    Flask学习笔记 异步CMS 五 1 环境 1 安装nvm 2 安装node 2 使用vue cli创建项目 3 安装相关插件 4 后台CMS开发 1 页面结构 1 app vue搭建结构 2 element icon组件的使用 3 ic
  • matlab rand randn 每次生成的随机数都一样的解决方案

    文章目录 问题说明 解决方案 例子 生成不重复的随机数 生成重复的随机数 结论 参考文献 问题说明 在Matlab应用中 我们经常需要用到随机数 比如rand randn 等函数 都是生成某一类随机数的函数 对于rand 函数来说 每一次启
  • HDR到底是什么?

    此文章转发自互联网 先感谢论坛好友 xiaoyuer520的耐心讲解及推荐这篇文章给我 我愿意分享给大家一起共同进步 谢谢 大家如果有像我一样的 看到文字多的帖子就看不下去 但又很想知道HDR是什么Dolby Vision和HDR10的区别
  • MySQL入门篇之Xtrabackup备份与恢复

    一 Xtrabackup介绍 MySQL冷备 mysqldump MySQL热拷贝都无法实现对数据库进行增量备份 在实际生产环境中增量备份是非常实用的 如果数据大于50G或100G 存储空间足够的情况下 可以每天进行完整备份 如果每天产生的
  • Vue2.7.14、vuecli@5.0.8 升级 vite@4.4.8

    项目背景 Vue2 7 14 vuecli 5 0 8 element ui 2 15 13 node14 18 3 本项目内部项目 不涉及CDN加速 vite安装 pnpm add vite 4 4 8 D 入口文件index html
  • Qt自定义窗口圆角

    Qt设置圆角 在Qt中一般设置窗口圆角有两种方式 QSS 通过paintEvent自绘窗口 QSS 设置圆角 这种设置圆角的方式相对来说比较灵活 但我们设置基类窗口 最外层窗口 用qss就很不方便 会收到后续qss的影响 另外当圆角设置大小
  • Docker 安装教程

    目录 一 离线安装 一 CentOS 离线安装 一 下载地址 1 选择系统的型号 选择linux CentOS 2 上传文件到CentOS 服务器 二 开始安装 1 解压压缩包 2 解压得到的文件复制到 usr bin目录下 3 注册doc
  • 想要好看的壁纸图片,用这个网站一键解决,不用爬虫也能实现爬虫效果,一键爬取图片网站所有的图片

    想要好看的壁纸图片 用这个网站一键解决 不用爬虫也能实现爬虫效果 一键爬取图片网站所有的图片 网站的地址 https extract pics 演示例子 图片网站 https www sohu com a 582693827 1211239
  • eclipse创建maven项目报Could not calculate build plan: Plugin org.apache.maven.plugins:maven-war-plugin:2.

    创建maven项目eclipse报下面错误 Could not calculate build plan Plugin org apache maven plugins maven war plugin 2 2 or one of its
  • 宋浩高等数学笔记(十二)无穷级数

    完结 宋浩笔记系列的最后一更 之后会出一些武忠祥老师的错题 笔记总结 10月份就要赶紧做真题了
  • C++多态----虚函数初级剖析

    多态说白了就是多种形态 在C 中不少的函数都可以实现多种形态 例如函数重载 运算符重载等等 这种重载一般都是在编译阶段时就已经确定了形态 这种多态 我们一般称之为静态多态 那么既然静态多态是在编译阶段就已经确定好了形态 那么动态多态 自然也
  • 项目有大量的spring日志,log配置level无效的解决方案

    思路 log配置文件的level无效 是因为启动spring的时候 log尚未加载 解决方案 1 web xml中的log监听器的启动顺序早于spring监听器 2 log配置文件生效后 可根据日志种类设置level进行拦截 参考 web
  • 黑暗精灵修改为国内源

    第1步 修改 etc pacman d mirrorlist vim etc pacman d mirrorlist 1 第2步 修改 etc pacman d blackarch mirrorlist vim etc pacman d b
  • python 安装whl文件

    python 安装whl文件 使用场景 在terminal中 通过 pip install 命令进行第三方模块安装时 由于网络获其他原因会使得第三方模块下载失败 导致安装失败 此时 我们可以先通过下载网址将第三方模块包手动下载到本地 再手动
  • Linux系统下 查找已安装软件的命令

    1 find 使用find查找文件的所在路径 find 查找路径 查找参数 在根目录下查找以 conf结尾的文件 find name conf 2 ps 通过查找进程的方法找到对应的包的路径 ps ef grep mongo 也可以简写成
  • mysql5.7.13+VS3013 源代码阅读调试

    之前写Java 对C make cmake都不是很熟 所以参考了以下这些前辈写的博客 最后成功搭建了mysql5 7 13 VS3013调试环境 自己总结了需要需要注意的几点 Windows VS2012环境下编译调试MySQL源码 一 W
  • SQLServer如果指定列列值相同则用逗号拼接其他指定列数据 stuff函数+for xml path

    for xml path 就是将 sql 查询出来的内容以XML的格式显示出来 Stuff 查询字符串 开始位置 数字 长度 数字 需插入的字符串 示例 55替换abcd123字符串中的a 示例 55替换abcd123字符串中的abcd 示
  • vue+Echarts绘制k线图(二)--分时图和交易量图

    目录 1 前言 2 分时图 2 1 vue引入Echarts 2 2 分时图介绍 2 3 分时折线图配置 2 4 组合交易量图 2 5 鼠标指示数据设置 2 6 项目完整代码 3 总结 1 前言 近来发现Echarts API越发的强大 对
  • 二分查找的各种应用详解(C++)

    基本概念 Binary Search 二分查找也称折半查找 它是一种效率较高的查找方法 使用二分查找要求线性表必须采用顺序存储结构 而且表中元素按关键字有序排列 基本原理 查找 因为序列已经单调且有序排列 从中间位置开始比较 一次可以排除一