折半查找二分查找

简介

折半查找也就是二分查找,也可以叫二分法,本质上都是一样的,通过比对中间值与目标值,一次性就能筛掉一半的数字。

举例:

一个猜数字游戏,让你来猜1-100中我选中的数,如果猜中游戏结束,如果猜的数字比选的数字大,告诉你猜的数大了,反之亦然。

如何针对上述游戏,寻找到一个最快的办法呢?—— 拼运气 或 折半查找

每次猜的数字为区间范围的中数,这样最多在 \log_{2}N 次内一定能找到!

假设选中的数字为 target = 77

第一次:选(1 + 100) / 2 = 50(这里取整数即可)  -> 小了

第二次:选(50 + 100) / 2 = 75  ->  小了

第三次:选(75 + 100) / 2 = 87  ->  大了

第四次:选(75 + 87) / 2 = 81  ->  大了

第五次:选(75 + 81) / 2 = 78  ->  大了

第六次:选(75 + 78) / 2 = 76  ->  小了

第七次:选(76 + 78) / 2 = 77  ->  对了 

通过上述案例,我们能发现,每次在进行查找的时候能够排除一半的错误答案!相当于对所有可能的个数除2。因此折半查找的时间复杂度   \log_{2}N。100个数,最多只要7次就能找到!

虽然折半查找效率这么高,但也是有缺点的~互联网没有“银弹”~

折半查找最大的问题在于,要求你进行查找的数据集必须是有序的!!!所以在编程的时候,可能需要你先进行一次排序~

编码

思路:

1.如果没告诉你数组是有序的,需要对数组进行一次排序(假设是有序的)

2.计算中间数在数组的位置

3.将中间数与目标值进行比对,如果中间数小了,就去右边的区间继续查找,如果中间数大了,就去左边的区间继续查找,如果刚好相等,说明找到了,返回即可。

下述折半查找的代码是基于比区间来写的,一定需要注意!!!否则会导致最终结果不对,这是二分法的细节问题(很容易出错)! 

#include <stdio.h>int BinarySearch(const int* arr, int target, int size)
{int left = 0;int right = size - 1;while (left <= right) //这里定义的是[left, right] 闭区间,一定要注意{//计算中间的那个元素的下标int mid = left + (right - left) / 2;//如果要找的数小于中间的那个数if (target < arr[mid])right = mid - 1;else if (target > arr[mid])left = mid + 1;//如果找到了就直接返回这个元素的下标elsereturn mid;}
}int main()
{int arr[] = { 5,8,10,23,48,66,88,100 };int target = 48;//计算数组中元素个数int size = sizeof(arr) / sizeof(arr[0]);int index = BinarySearch(arr, target, size);printf("找到了,这个数在数组中的下标为:%d", index);return 0;
}

优化

上述的代码是针对目标值出现在数组的情况,不适用于更普遍一半的情况。在C++标准库中就提供了折半查找这个函数,他的功能是,找到目标值在数组中第一次出现的位置,如果数组中未存在目标值,则找到插入位置。

通过观察上述折半查找算法的过程,我们会发现,

1.如果中间值arr[mid]大于目标值target,则arr[mid+1]~最后 的值都大于目标值taget。arr[left]~arr[mid]可能小于等于目标值target。

2.如果中间值arr[mid]小于目标值target,则arr[left]~arr[mid] 的值都小于目标值target。

最终我们得出,left左边的值都是小于目标值的,right右边的值都是大于目标值的。

如果要找到插入的位置,则找到第一个大于等于目标值的位置。

代码

int searchInsert(int* nums, int numsSize, int target)
{int left = 0;int right = target - 1;while(left <= right){int mid = left + (right -left) / 2;if(nums[mid] < target)left = mid + 1;elseright = mid - 1;}return left;
}

上述代码,将中间值大于等于的情况进行了合并。为的是找到第一个出现的位置,并且代表的含义也变了——right右边的数是大于等于目标值target的。

举个例子:

int arr[] = {1,2,3,3,3,3,5,6};
target = 3

要去查找第一个3,我们的中间值第一次找到的3是第二个,但我们要找的是第一个,所以需要继续缩小右边界,才能找到。

至于最后为什么返回的是left呢?因为根据代码,left左边的值是小于目标值的,right右边的值是大于等于目标值的,而最终left和right的位置一定是满足right在left的左边且相差一个元素,于是就返回left了。

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

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

相关文章

elementUI输入框/选项卡与百度地图联动

文章目录 输入框/选项卡与百度地图联动示例html部分用到的插件main.js 输入框/选项卡与百度地图联动 示例 输入框/选项卡与百度地图联动 html部分 <template><el-form ref"Froms" :model"formData" label-width"120px"><el-for…

露营地管理小程序基于ThinkPHP+FastAdmin+UniApp开发

应用介绍 本文来自&#xff1a;露营地管理小程序基于ThinkPHPFastAdminUniApp开发 - 源码1688 基于ThinkPHPFastAdminUniApp开发的现代化的露营地管理小程序&#xff0c;是专为露营业务设计开发小程序应用。平台拥有多角色管理&#xff0c;同时具有营位预定、门票购买等功能模…

【距离四六级只剩一个星期!】刘晓艳四级保命班课程笔记(2)(可分享治资料~)

这一节是专门的听力课程&#xff0c;众所周知&#xff0c;咱们刘晓艳刘老师的口语不是特别的突出&#xff0c;当然口才是一流的☝️。 文章目录 听力预判听前预判 听力过程八大出题关键点视听一致同义转换 听完一道题后平时练习精听步骤 听力预判 听前预判 画关键词&#xff…

融合通信系统 | 让传统通信沟通无边界

随着通信技术以及互联网的发展&#xff0c;融合通信在各行各业中的应用日益增多&#xff0c;融合通信多样的通信方式为行业用户带来了极佳的通信体验&#xff0c;助力各行各业蓬勃发展&#xff0c;同时也为人们的生活和工作带来了极大的便利和效率。 融合通信系统是一种集成多种…

PHP 操作日期各种转换,常见日期转换,涉及聊天时间转换、涉及日周月年转换、涉及到图表日期转换

日期操作 一、根据日期生成日期数组 /*** 根据指定日期生成日期数组* param $start_time 开始时间* param $end_time 结束时间* return array 返回数组结果*/ function createDateArr($start_time, $end_time) {$open_start_time $start_time;$open_end_time $end_ti…

leetcode 1103.分糖果II

思路&#xff1a;模拟 其实就是用num_people取余就行了&#xff0c;如果说特别一点的话&#xff0c;就是candies的判断了。 如果说当前的candies能够分发出来&#xff0c;那么这个candies就按照题目要求分发即可&#xff1b;如果说不够&#xff0c;那么只能分给当前小朋友can…

C语言基础——数组(2)

ʕ • ᴥ • ʔ づ♡ど &#x1f389; 欢迎点赞支持&#x1f389; 个人主页&#xff1a;励志不掉头发的内向程序员&#xff1b; 专栏主页&#xff1a;C语言基础&#xff1b; 文章目录 前言 一、二维数组的创建 1.1 二维数组的概念 1.2二维数组的创建 二、二维数组…

岁月情深,爱如初见——我爸爸的老年爱情故事

​在那个泛黄的老相册里&#xff0c;藏着一对青涩的恋人&#xff0c;他们的眼神清澈而坚定&#xff0c;仿佛早已约定了今生的不离不弃。那便是我的爸爸和他的爱人&#xff0c;妈妈。时光荏苒&#xff0c;转眼间&#xff0c;两人已是白发苍苍的老人&#xff0c;但他们的爱情故事…

网络安全中攻击溯源方法

目前网络攻击已经成为常见的安全威胁之一&#xff0c;其造成的危害和损失都是不可估量的&#xff0c;因此网络攻击受到了高度重视。而当我们遭遇网络攻击时&#xff0c;攻击溯源是一项非常重要的工作&#xff0c;可以帮助我们迅速发现并应对各类网络攻击行为&#xff0c;那么网…

Jetpack架构组件_LifeCycle组件

1.LifeCycle组件 LifeCycle组件可以让我们自定义的类能主动感知到Activity、Fragment、Application、Service等系统组件的生命周期。 我们以百度定位为例&#xff0c;我们一般在Activity生命周期的onCreate回调函数里调用自定义类LocationService的Start()方法&#xff0c;在o…

四川古力未来科技抖音小店:诚信之选,品质铸就信赖之路

在当今这个数字化、网络化的时代&#xff0c;电商平台如雨后春笋般涌现&#xff0c;抖音小店作为其中的佼佼者&#xff0c;以其独特的经营模式和广泛的用户基础&#xff0c;吸引了越来越多的消费者。而在这众多的抖音小店中&#xff0c;四川古力未来科技抖音小店凭借其卓越的品…

【HarmonyOS】应用屏蔽截屏和录屏

【HarmonyOS】应用屏蔽截屏和录屏 一、问题背景&#xff1a; 金融类或者高密性质的应用APP&#xff0c;对于截屏和录屏场景&#xff0c;某些业务下是禁止不允许。 目前这种场景的需求也是非常有必要的&#xff0c;很多电诈都是通过远程录屏软件&#xff0c;获取到账户密码或者…

头颈肿瘤在PET/CT中的分割:HECKTOR挑战赛| 文献速递-深度学习肿瘤自动分割

Title 题目 Head and neck tumor segmentation in PET/CT: The HECKTOR challenge 头颈肿瘤在PET/CT中的分割&#xff1a;HECKTOR挑战赛 01 文献速递介绍 高通量医学影像分析&#xff0c;常被称为放射组学&#xff0c;已显示出其在揭示定量影像生物标志物与癌症预后之间关…

基于单片机的超声波倒车雷达设计

摘 要&#xff1a;文 章设计了一种基于单片机的超声波倒车雷达系统&#xff0c;以 AT89C51 型单片机作为控制核心&#xff0c;集距离测量、显示&#xff0c;方位显示和危险报警于一体&#xff0c;以提高驾驶者在倒车泊车时的安全性和舒适性。本设计采用 Keil 软件对系统程序…

Mysql全文搜索和LIKE搜索有什么区别

全文搜索和LIKE的区别 性能&#xff1a;在大数据集上&#xff0c;全文搜索通常比LIKE查询更快&#xff0c;因为它使用了专门的索引结构。 功能&#xff1a;全文搜索提供了更丰富的查询功能&#xff0c;如多个关键词的搜索、自然语言搜索、布尔搜索等。而LIKE通常只支持简单的…

已办理劳务资质,为何无法在全国建筑市场网查询到企业?

已办理劳务资质的企业无法在全国建筑市场网&#xff08;四库一平台&#xff09;查询到&#xff0c;可能的原因如下&#xff1a; 数据更新延迟&#xff1a; 全国建筑市场监管公共服务平台&#xff08;四库一平台&#xff09;的数据更新可能存在延迟。新获得的劳务资质信息在平台…

第一次参加学术会议?来看看这份NeurIPS 2024的参会攻略

会议之眼 快讯 嘿&#xff0c;亲爱的学者们&#xff01;有没有还没参加过学术会议的同学呢&#xff1f;别担心&#xff0c;今天小编就来给大家分享一份超实用的参会攻略&#xff0c;以人工智能领域备受瞩目的NeurIPS 2024为例&#xff0c;让你第一次参加学术会议就能像个老手一…

day4 数1 隐函数

基础知识 隐函数 &#xff1a;一个方程里边 使x有1个y与之对应 函数的有界性 f(X) 的值大于-M并小于M 单调性 可以用定义发判断单调性 定义法 奇函数 奇函数关于原点对称&#xff0c;偶关于x对称 定义域要关于原点对称 任何一个函数可以写成奇函数偶函数的形式 复合函数的…

实验室原始记录电子化管理的发展及应用

实验室原始记录电子化管理的发展及应用&#xff0c;主要体现在以下几个方面&#xff1a; 一、发展背景与意义 随着科技的进步和实验室管理的现代化&#xff0c;实验室原始记录电子化发展已成为必然趋势。传统的实验室原始记录方式主要依赖于纸质文档&#xff0c;这种方式存在诸…

gorm/gin框架实战

gorm/gin框架实战 项目简介 学习源视频&#xff1a;【最新Go Web开发教程】基于gin框架和gorm的web开发实战 (七米出品)_哔哩哔哩_bilibili 本博客为我的学习笔记。 项目目标&#xff1a;实现一个备忘录工具(当然不支持alert)&#xff0c;仅仅是可以记录待办事项。 实现了…