iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言中二分查找怎么用
  • 310
分享到

C语言中二分查找怎么用

2023-06-29 17:06:50 310人浏览 八月长安
摘要

这篇文章主要介绍了C语言中二分查找怎么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。基础的二分查找先来回顾下基础的二分查找的基本框架,一般实际场景都是查找和 target

这篇文章主要介绍了C语言中二分查找怎么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

    基础的二分查

    找先来回顾下基础的二分查找的基本框架,一般实际场景都是查找和 target 相等的最左侧的元素或者最右侧的元素,代码如下:

    查找左侧边界

    int binary_search_firstequal(vector<int> &vec, int target){    int ilen = (int)vec.size();    if(ilen <= 0) return -1;    int left = 0;    int right = ilen - 1;    while (left <= right)    {        int mid = left + (right - left) / 2;        //找到了目标,继续向左查找目标        if (target == vec[mid]) right = mid - 1;        else if(target < vec[mid]) right = mid -1;        else left = mid + 1;            }    if(right + 1 < ilen && vec[right + 1] == target) return right+1;    return -1;}

    查找右侧边界

    int binary_search_lastequal(vector<int> &vec, int target){    int ilen = (int)vec.size();    if(ilen <= 0) return -1;    int left = 0;    int right = ilen - 1;    while (left <= right)    {        int mid = left + (right - left) / 2;        //找到了目标,继续向右查找目标        if (target == vec[mid]) left = mid + 1;        else if(target < vec[mid]) right = mid -1;        else left = mid + 1;            }    if(left - 1 < ilen && vec[left - 1] == target) return left - 1;    return -1;}

    二分查找问题分析

    二分查找问题的关键是找到一个单调关系,单调递增或者单调递减。

    我们把二分查找的代码简化下:

    int target;             // 要查找的目标值vector<int> vec;        // 数组int left = 0;           // 数组起始索引int right = ilen - 1;   // 数组结束索引while (left <= right)   // 查找 target 位于数组中的索引{   int mid = left + (right - left) / 2;   if (target == vec[mid]) return mid;}

    上面的二分查找的单调关系是什么呢 ?是数组的索引和索引处元素的值,索引越大,元素的值越大,用伪代码表示形式如下:

    int func(vector<int>&vec,int index){    return vec[index];}int search(vector<int>&vec,int target){  while (left <= right)  {     int mid = left + (right - left) / 2;     if (target == func(vec,mid))     {         ....     }     else if(target > func(vec,mid))     {         ...     }     else     {         ...     }  }}

    上述伪代码中,我们把单调关系用一个函数 func 来表示,传入参数是数组以及数组索引,函数返回数组指定索引处的元素。

    在二分查找的 while 循环中 target 直接和 func 函数的返回值进行比较。

    听起来有些抽象,我们直接从 LeetCode 上选几道题来分析下。

    实例1: 爱吃香蕉的珂珂

    C语言中二分查找怎么用

    从题目的描述,跟有序数组完全不搭边,所以初看这道题,根本想不到用二分查找的方法去分析 。

    如果看完题目,没有任何思路的话,可以缕一缕题目涉及到的条件,看能否分析出一些有用的点 。

    • 题意分析

    • 珂珂要吃香蕉,面前摆了 N 堆,一堆一堆地吃

    • 珂珂 1 小时能吃 K 根,但如果一堆少于 K 根,那也得花一小时

    • 如果 1 堆大于 K 根,那么超过 K 的部分也算 1 小时

    • 问:只给 H 小时,珂珂要吃多慢(K 多小),才能充分占用这 H 小时

    一般题目的问题是什么,单调关系就跟什么有关,根据题意可知:珂珂吃香蕉的速度越小,耗时越多。反之,速度越大,耗时越少,这就是题目的 单调关系 。

    我们要找的是速度, 因为题目限制了珂珂一个小时之内只能选择一堆香蕉吃,因此速度最大值就是这几堆香蕉中,数量最多的那一堆, 最小速度毫无疑问是 1 了,最大速度可以通过轮询数组获得 。

    int maxspeed = 1;for(auto &elem : vec){    if(elem > maxspeed) maxspeed = elem;}+

    又因为珂珂一个小时之内只能选择一堆香蕉吃,因此,每堆香蕉吃完的耗时 = 这堆香蕉的数量 / 珂珂一小时吃香蕉的数量。根据题意,这里的 / 在不能整除的时候,还需要花费 1 小时吃完剩下的,所以吃完一堆香蕉花费的时间,可以表示成 。

    hour = piles[i] / speed;if(0 != piles[i] % speed) hour += 1;

    香蕉的堆数以及每堆的数量是确定的,要在 H 小时内吃完,时间是输入参数,也是确定的了,现在唯一不确定的就是吃香蕉的速度,我们需要做的就是在最小速度 到 最大速度之间找出一个速度,使得刚好能在 H 小时内吃完香蕉 。

    前面说到吃香蕉的速度和吃完香蕉需要的时间之间是单调关系,我们先把单调关系的函数定义出来 。

    // 速度为 speed 时,吃完所有堆的食物需要多少小时int eatingHour(vector<int>&piles,int speed){    if(speed <= 0) return -1;    int hour = 0;    for(auto &iter : piles)    {        hour += iter / speed;        if(0 != iter % speed) hour += 1;    }    return hour;}

    题目要求吃完香蕉的最小速度,也就是速度要足够小,小到刚好在 H 小时内吃完所有的香蕉,所以是求速度的左侧边界 。

    好了,分析完之后,写出代码:

    int minEatingSpeed(vector<int> &piles, int h){    //1小时最多能吃多少根香蕉    int maxcount = 1;    for (auto &iter : piles)    {        if (maxcount < iter) maxcount = iter;     }    //时间的校验    if (h < 1 || h < (int)piles.size() )  return -1;    int l_speed = 1;    int r_speed = maxcount;    while (l_speed <= r_speed)    {        int m = l_speed + (r_speed - l_speed) / 2;        // eatingHour 函数代码见上文        int hours = eatingHour(piles, m);        if (hours == h)        {            // 求速度的左侧边界            r_speed = m - 1;        }        else if (hours < h)        {            // hours 比 h 小,表示速度过大,边界需要往左边移动            r_speed = m - 1;        }        else        {            // hours 比 h 大,表示速度国小,边界需要往右边移动            l_speed = m + 1;        }    }    return l_speed;}

    上述代码中,我们列出了 while 循环中的 if 的所有分支,是为了帮助理解的,大家可自行进行合并。

    实例2:运送包裹

    C语言中二分查找怎么用

    题目要求 船的运载能力, 船的运载能力和运输需要的天数成反比,运载能力越大,需要的天数越少,运载能力越小,需要的天数越多,也即存在 单调关系,下面定义出单调关系的函数。

    //船的载重为 capcity 时,运载 weights 货物需要多少天int shipDays(const vector<int> &weights, int capacity){    //船载重校验    if(capacity <= 0) return -1;    int isize = (int)weights.size();    int temp = 0;    int days = 0;    for(int i = 0; i < isize; ++i)    {        if(temp + weights[i] <= capacity)        {            temp += weights[i];            continue;        }        ++days;        temp = weights[i];    }    //还有剩余的,需要额外在运送一趟    if(temp > 0)  ++days;    return days;}

    题目中隐含的几个信息:

    • 船的最小载重需要大于等于传送带上最重包裹的重量,因为每次至少要装载一个包裹

    • 船的最大载重等于传送带上所有包裹的总重量,也即所有的包裹可以一次全部装上船

    • 船每天只能运送一趟包裹

    确定了船的运载范围后,相当于确定了二分查找的区间,另外,题目求的是船的最小运载能力,相当于求运载能力的左侧边界。

    分析到这里,就可以写出基本的查找框架了,这里直接给出代码了。

    int shipWithinDays(vector<int> &weights, int days){    int isize = (int)weights.size();    if (isize <= 0) return 0;    //最小载重,需要等于货物的最大重量    int mincapacity = 0;    //最大载重,全部货物重量的总和    int maxcapacity = 0;    for (auto &iter : weights)    {        maxcapacity += iter;        if (iter > mincapacity)        {            mincapacity = iter;        }    }    int l = mincapacity;    int r = maxcapacity;    while (l < r)    {        int m = l + (r - l) / 2;        int d = shipDays(weights, m);        if (d == days)        {            r = m - 1;        }        else if (d < days)        {            // d 比 days 小,表示船载重太大,载重边界需要往左移            r = m - 1;        }        else        {            // d 比 days 大,表示船载重太小,载重边界需要往右移            l = m + 1;        }    }    return l;}

    感谢你能够认真阅读完这篇文章,希望小编分享的“C语言中二分查找怎么用”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网其他教程频道,更多相关知识等着你来学习!

    --结束END--

    本文标题: C语言中二分查找怎么用

    本文链接: https://www.lsjlt.com/news/325919.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • C语言中二分查找怎么用
      这篇文章主要介绍了C语言中二分查找怎么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。基础的二分查找先来回顾下基础的二分查找的基本框架,一般实际场景都是查找和 target ...
      99+
      2023-06-29
    • C语言二分查找法怎么用
      这篇文章主要讲解了“C语言二分查找法怎么用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C语言二分查找法怎么用”吧!示例 1:输入: nums = [-1,0,3,5,9,12], targ...
      99+
      2023-06-30
    • C语言算法--有序查找(折半查找/二分查找)
      目录题目解法一: 挨个遍历方法二:折半查找/二分查找(仅适用于有序查找)总结题目 首先我们来把题目瞅一眼: 在一个有序数组中查找具体的某个数字n。 编写int binary_sea...
      99+
      2022-11-12
    • 用C语言实现二分查找算法
      目录一.前言二.二分查找法1.什么是二分查找法2.如何用c语言来实现二分查找法三.总结总结一.前言 假如今天我们需要在一个有序的数组中来寻找一个数的下标,就用"1,2,3,...
      99+
      2022-11-12
    • C语言二分查找图文详解
      目录一、二分查找算法1.假定给定的数组中元素个数为奇数个2.假定给定的数组为偶数个3.假定给定的数不在此数列中二、分支语句中应注意的小点1.悬空else语句2.switch语句中的b...
      99+
      2023-05-18
      c语言二分查找 c语言二分查找代码 c语言二分查找法
    • C语言中二叉查找树怎么实现
      本文小编为大家详细介绍“C语言中二叉查找树怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言中二叉查找树怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。二叉查找树性质1、二叉树每个树的节点最多有...
      99+
      2023-06-16
    • C语言详细讲解二分查找用法
      目录【力扣题号】704.二分查找 力扣题目链接 示例 1: 输入: nums = [-1,0,3,5,9,12], target = 9     输出:...
      99+
      2022-11-13
    • 详解C语言中二分查找的运用技巧
      目录基础的二分查查找左侧边界查找右侧边界二分查找问题分析实例1: 爱吃香蕉的珂珂实例2:运送包裹前篇文章聊到了二分查找的基础以及细节的处理问题,主要介绍了 查找和目标值相等的元素、查...
      99+
      2022-11-13
    • 怎么在c语言中使用二分法查找数组中的元素
      今天就跟大家聊聊有关怎么在c语言中使用二分法查找数组中的元素,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。c语言二分法实现查找数组元素的方法:递归算法#include<stdi...
      99+
      2023-06-14
    • C语言巧用二分查找实现猜数游戏
      目录(壹)二分查找  1.1  何为二分查找  1.2  二分查找的原理  1.3  查找条件  1.4&nbs...
      99+
      2022-11-13
    • C#二分查找算法怎么用
      这篇“C#二分查找算法怎么用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C#二分查找算法怎么用”文章吧。1、定义:折半搜索...
      99+
      2023-06-30
    • C语言编程之初识数组线性查找和二分查找
      目录线性查找二分查找先来了解一下什么是查找, 额,好吧,这没什么可了解的, 就是查找数组中的某个元素的位置或是否存在。 就这,没了。直接了解查找算法吧。 线性查找 线性查找与二分查找...
      99+
      2022-11-12
    • C语言怎么通过二分查找实现猜数字游戏
      本文小编为大家详细介绍“C语言怎么通过二分查找实现猜数字游戏”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言怎么通过二分查找实现猜数字游戏”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。二分查找题目: 在一个...
      99+
      2023-07-05
    • Python语言实现二分法查找
      前言: 二分法也就是二分查找,它是一种效率较高的查找方法 假如公司新来了一个人,叫张三,他是你们公司第47个人,过了一段时间后,有些人呢看张三不爽,离职了,那这时候张三肯定不是公司第...
      99+
      2022-11-13
    • C语言数据结构之二分法查找详解
      问题:在有序数组中查找给定元素的下标goal。 在查找一个数组元素的下标,可以用循环来解决,但是如果一个数足够大,比如说手机的价格,用循环来查找,就相当于叫一个人猜,从0开始,需要猜...
      99+
      2022-11-13
    • 一篇文章带你了解C语言二分查找
      目录总结我们常常需要对数据进行查找,修改,查找数据有许多方法,我们先看看最简单的顺序查找 int main() { int i, k = 0; scanf("%d", &am...
      99+
      2022-11-12
    • C语言如何使用二分查找实现猜数游戏
      这篇文章给大家分享的是有关C语言如何使用二分查找实现猜数游戏的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。(壹)二分查找 1.1  何为二分查找折半查找,也称二分查找,在某些情况下相比于顺序查...
      99+
      2023-06-29
    • C语言基础之二分查找知识最全汇总
      目录一、前言二、原始二分查找三、二分查找的变化之数组元素重复四、轮转循环五、杨氏矩阵六、用二叉树来描述二分查找七、二分查找的概率问题一、前言 在自学二分查找的过程中我想到了一些变化问...
      99+
      2022-11-12
    • C语言通过二分查找实现猜数字游戏
      目录二分查找二分查找的思想二分查找的条件二分查找的实现过程代码举例猜数字游戏游戏说明猜数字游戏思想代码实现整体代码演示二分查找 题目: 在一个有序数组中查找具体的某个数字n。 首先我...
      99+
      2023-02-03
      C语言 二分查找实现猜数字 C语言 二分查找 C语言 猜数字
    • C语言面试C++二维数组中的查找示例
      目录二维数组中的查找面试题3:暴力遍历动态基点操作二维数组中的查找 面试题3: 似题: 我做过这个类似的有杨氏矩阵为背景的,实际上是一样的 暴力遍历 二维数组暴力遍历的话时间复杂度...
      99+
      2022-11-12
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作