基础算法--二分查找

news2024/11/26 2:36:43

二分查找

算法原理

1. 简介

故事分享🏬:

有一天小明到图书馆借了 N 本书,出图书馆的时候,警报响了,于是保安把小明拦下,要检查一下哪本书没有登记出借。小明正准备把每一本书在报警器下过一下,以找出引发警报的书,但是保安露出不屑的眼神:你连二分查找都不会吗?于是保安把书分成两堆,>让第一堆过一下报警器,报警器响;于是再把这堆书分成两堆…… 最终,检测了 logN 次之后,保安成功的找到了那本引起警报的书,露出了得意和嘲讽的笑容。于是小明背着剩下的书走了。 从此,图书馆丢了 N - 1 本书。

保安怎么知道只有一本书📖没有登记出借,万一全部都没有登记呢​?

这个故事其实说出了二分查找需要的条件

  • 用于查找的内容逻辑上来说是需要有序的
  • 查找的数量只能是一个,而不是多个

比如在一个有序的数组并且无重复元素的数组中,例如[1, 2, 3, 4, 5, 6],需要查找3的位置就可以使用二分查找。

在二分查找中,目标元素的查找区间的定义十分重要,不同的区间的定义写法不一样

二分法的思想很简单,因为整个数组是有序的,数组默认是递增的。

  • 首先选择数组中间的数字和需要查找的目标值比较
  • 如果相等最好,就可以直接返回答案了
  • 如果不相等
    • 如果中间的数字大于目标值,则中间数字向右所有数字都大于目标值,全部排除
    • 如果中间的数字小于目标值,则中间数字向左所有数字都小于目标值,全部排除

二分法就是按照这种方式进行快速排除查找的

不用去纠结数组的长度是奇数或者偶数的时候,怎么取长度的一半,以下是说明,可以跳过。

当数组的长度为奇数的时候:

在这里插入图片描述
是奇数的情况很简单,指向中间的数字很容易理解,如果需要查找的数字为29

因为29大于中间的数字大于11,所以左边的所有数字全部排除

在这里插入图片描述

当数组的长度为偶数的时候:

在这里插入图片描述
这个时候中间的数字两边的数字数量就不一样了,如果长度为偶数就为上图中间的数字两边的相差为 1

但是千万不要一直纠结中间的数字两边的数字数量不一样这个问题,因为:

两边数量不一样是一定会出现的情况
但是这种情况并不影响我们对中间数字和目标数字大小关系的判断
只要中间数字大于目标数字,就排除右边的
只要中间数字小于目标数字,就排除左边的

所以数组长度是偶数还是奇数这个真的不重要,不影响怎么排除的问题,无非是多排除一个数字或者少排除一个数字
  • 真正影响的是中间那个数字到底该不该加入下一次的查找中,也就是边界问题

整数二分查找

有序无重复整数二分

新的视角审视二分查找(划分红蓝区域)

有N个元素的数组,前K个元素区域为蓝色,后N-K个为红色。然而在这个问题中,蓝红边界的位置是未知的,即K是未知的。
在这里插入图片描述
在我们拿到数组的时候,整个数组默认都是灰色区域,未知的。
在这里插入图片描述
这个问题,是把蓝红边界找出来
在这里插入图片描述

蓝红区域思想示例

下面的蓝色就是满足查找条件的判断边界。
将数组左侧的蓝色指针,持续不断的向目标区域扩展,
在这里插入图片描述
在这里插入图片描述
同理,红色指针 不断向左移动,红色区域不断被拓展
在这里插入图片描述
在这里插入图片描述
加快这一过程,直接看中间值,他的颜色为蓝色
在这里插入图片描述
就意味着,他之前的颜色都是蓝色
在这里插入图片描述
直接把蓝色指针移动到 中间位置4上
在这里插入图片描述
剩下的中间值根据中间值,查看颜色
在这里插入图片描述
在这里插入图片描述
一开始定义蓝红指针在数组两侧
在这里插入图片描述
然后通过二分,将蓝红指针迅速向目标值靠近
在这里插入图片描述
在这里插入图片描述

蓝红区域到最后,正好指向蓝红边界,需要根据实际情况决定是返回 l 还是 r。

在这里插入图片描述
在这里插入图片描述

C++代码 有序无重复整数二分

#include <iostream>
using namespace std;

int n, val;
int q[] = {1,2,3,4,5};


int binary_search(int q[], int val)
{
	int left = -1;
	int right = n;
	
	while (left + 1 != right)
	{
		int mid = left + right >> 1;
		if (q[mid] <= val) left = mid;
		else right = mid;
	}
	
	if(q[left] == val) return left;
	else return -1;
}

int main(){
	cin >> n >> val;
	
	int res = binary_search(q, val);
	cout << res;
	
	return 0;
}

python代码 有序无重复整数二分

def binary_serach(li, val):
    left = -1
    right = len(li)

    while left + 1 != right:
        mid = (left + right) // 2
        if li[mid] <= val:
            left = mid
        else:
            right = mid

    if li[left] == val:
        return left
    else:
        return -1


# 有序序列,且无重复值
li = [i for i in range(5)]
index = binary_serach(li, 5)
print(index)

有序有重复值二分(条件查找)

案例:从下列数组中根据各种条件查找:
在这里插入图片描述
查找需求:

  • 找到第一个">=5" 的元素
  • 找到最后一个"<5"的元素
  • 找到第一个">5"的元素
  • 找到最后一个"<=5"的元素

这四个需求,表面上是相似的,但是答案却不同
在这里插入图片描述
可见,如果用二分查找来处理这个问题,边界问题处理不好,一不小心就会出错。
在这里插入图片描述
这题第一个问题代码示例,后面更改IsBlue判断条件和 返回值r或者l
IsBlue 条件全部写成是 小于等于 待查找值
看题目要求,IsBlue 条件 和题目 小于或者小于等于时 同步 并且返回 l
题目是 大于 或者 大于等于时,IsBlue 条件 取反 小于等于或者小于时 同步 并且返回 r

C++代码实现查找 找到第一个">=5" 的元素
#include <iostream>
using namespace std;

int n = 8;
int q[] = {1,2,3,5,5,5,8,9};


int binary_search(int q[], int val)
{
	int left = -1;
	int right = n;
	
	while (left + 1 != right)
	{
		int mid = left + right >> 1;
		if (q[mid] < val) left = mid;
		else right = mid;
	}
	
	if(right > n - 1) return -1;
	
	else return right;
}

int main(){
	int val;
	cin >> val;
	
	int res = binary_search(q, val);
	cout << res;
	
	return 0;
}
python代码实现查找 找到第一个">=5" 的元素
def binary_serach_1(li, val):
    """
    找到第一个">=5"的元素
    """
    l = -1
    r = len(li)
    while l + 1 != r:
        mid = (l + r) // 2
        if li[mid] < val:
            l = mid
        else:
            r = mid

    if r > len(li) - 1:
        return -1
    else:
        return r

浮点数二分查找

案例:通过二分查找的方式计算 根号2,要求误差小于 10^-6

求平方根,首先答案在 0–输入值x 之间
|0------------------x|
答案在这之间

C++代码实现求平方根
#include <iostream>
using namespace std;

int main(){
	double x;
	cin >> x;
	
	double l = 0, r = x;
	while(r - l > 1e-6) 
	{
		double mid = (l + r) / 2;
		if(mid * mid >= x) r = mid;
		else l = mid;
	}
	
	printf("%lf\n", l);
	
	return 0;
}
python代码实现求平方根
def binary_float_serach(val):
    """求平方根"""
    l, r = 0, val
    while r - l > 1e-6:
        mid = (l + r) / 2
        # 说明答案在mid的左边
        if mid * mid >= val:
            r = mid
        else:
            l = mid

    return l

在这里插入图片描述

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

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

相关文章

C语言基本知识

基础 第一个函数 argc代表参数个数argument count。argv代表参数value&#xff0c;第一个为放的是文件名&#xff0c;后面是传入的参数。 编译过程 预处&#xff1a;gcc -E hello.c -o hello.i编译&#xff1a;gcc -S hello.c(.i) -o hello.s汇编&#xff1a;gcc -c hello.c…

2023年09月数据库流行度最新排名

点击查看最新数据库流行度最新排名&#xff08;每月更新&#xff09; 2023年09月数据库流行度最新排名 TOP DB顶级数据库索引是通过分析在谷歌上搜索数据库名称的频率来创建的 一个数据库被搜索的次数越多&#xff0c;这个数据库就被认为越受欢迎。这是一个领先指标。原始数…

C语言“牵手”1688商品详情数据方法,1688商品详情API接口,1688API申请指南

1688是中国最大的自营式电商企业&#xff0c;在线销售计算机、手机及其它数码产品、家电、汽车配件、服装与鞋类、奢侈品、家居与家庭用品、化妆品与其它个人护理用品、食品与营养品、书籍与其它媒体产品、母婴用品与玩具、体育与健身器材以及虚拟商品等。 1688平台的商品详情…

route命令小结

Destination: 如果不满足该列的任何一个ip,则走默认的default Gataway: *是 不指定gateway.有的系统是0.0.0.0,与*意义相同 Genmask: 0.0.0.0是不指定掩码, 255.255.0.0掩码了16位,172.17 开头的ip,会走这个网关 255.255.255.0掩码了16位,192.168.0 开头的ip都会走这个网关 当是…

基于Alexnet深度学习网络的人员口罩识别算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 file_path1 test\mask\;% 图像文件夹路径 %获取测试图像文件夹下所有jpg格式的图像文件…

网工内推 | 国企专场,网络运维工程师,华为/思科认证优先

01 中百集团 招聘岗位&#xff1a;运维工程师 职责描述&#xff1a; 1、对集团内使用云计算架构&#xff08;Kubernetes&#xff09;的系统进行规划、运维及管理相关工作。 2、对集团数据中心系统的大数据基础架构&#xff08;Cloudera Distribution Hadoop&#xff09;的规划…

vue3项目修改浏览器的项目icon小图标

修改vue3项目的浏览器的图标 vue2修改图标

微信的标签怎样管理?怎样标签群发更高效?(建议收藏)

01 管理标签的意义 随着时间的递增&#xff0c;微信好友越来越多&#xff0c;很容易就超过了上千人&#xff0c;如果这时候&#xff0c;还没有具备管理标签的意识&#xff0c;那就必须得提上日程了。 管理标签有如下几点意义&#xff1a; 1、方便找到对方 2、分组备注&am…

HarmonyOS/OpenHarmony(Stage模型)应用开发单一手势(三)

五、旋转手势&#xff08;RotationGesture&#xff09; RotationGesture(value?:{fingers?:number; angle?:number}) 旋转手势用于触发旋转手势事件&#xff0c;触发旋转手势的最少手指数量为2指&#xff0c;最大为5指&#xff0c;最小改变度数为1度&#xff0c;拥有两个可…

分享一下在微信上有哪些微信活动可以做

微信营销活动是吸引更多用户和提高品牌知名度的有效策略。下面是一些微信营销活动的做法&#xff1a; 抽奖活动&#xff1a;通过设置奖品和参与条件&#xff0c;吸引用户参与抽奖活动。例如&#xff0c;可以设置关注公众号、转发活动页面等条件&#xff0c;吸引更多用户参与抽奖…

Redis 分布式锁

面试题&#xff1a; Redis除了拿来做缓存&#xff0c;你还见过基于Redis的什么用法&#xff1f; 1.数据共享&#xff0c;分布式Session 2.分布式锁 3.全局ID 4.计算器、点赞 5.位统计 6.购物车 7.轻量级消息队列&#xff1a;list、stream 8.抽奖 9.点赞、签到、打卡 10.差集交集…

手机技巧:推荐7款日常生活中实用的工具类app

目录 1、DeepL-翻译神器 2、我的倒计时 3、醒图APP-图片美化神器 4、DAMA 5、氢时光 今天给大家推荐7款日常生活中实用的工具类app&#xff01; 1、DeepL-翻译神器 Deepl手机版是一款强大简便的在线翻译工具&#xff0c;与全球最精确的语言词典系统连接&#xff0c;您可以…

二进制安全虚拟机Protostar靶场(3)溢出控制程序指针,基础知识讲解 Stack Three,Stack Four

前言 这是一个系列文章&#xff0c;之前已经介绍过一些二进制安全的基础知识&#xff0c;这里就不过多重复提及&#xff0c;不熟悉的同学可以去看看我之前写的文章 二进制安全虚拟机Protostar靶场 安装,基础知识讲解,破解STACK ZERO https://blog.csdn.net/qq_45894840/artic…

生信分析-在线小工具|永久收藏

生信分析软件在生物信息学研究中可以帮助研究人员处理、分析和解释生物学数据&#xff0c;从而揭示生物学系统的结构和功能。如数据处理和格式转换、序列比对和测序数据分析、基因组注释和功能预测、基因表达分析、变异检测和遗传分析、数据可视化等软件功能都可以提高研究效率…

一文讲透:CRM客户管理系统的功能有哪些?

CRM客户管理系统的功能有哪些&#xff1f; CRM客户管理系统是一种能够帮助企业管理客户关系的软件系统&#xff0c;它包括了客户信息管理、销售管理、客户服务管理、营销管理和数据分析等功能&#xff0c;能够帮助企业更好地了解客户需求&#xff0c;优化销售流程&#xff0c;…

智慧体育时代来了 | AI融合体育,从观赛到备赛,看它如何全面覆盖

近期&#xff0c;2023年篮球世界杯的赛事在网络上掀起一股体育竞技狂潮&#xff0c;俗话说“体育强则中国强&#xff0c;国运兴则体育兴。”在我国科技的不断进步下&#xff0c;人工智能在各个领域得到了不同程度的运用&#xff0c;在体育竞技中也不例外。国家体育总局发布的《…

ADS仿真设计低噪放大器

ATF54143的zap文件下载&#xff1a; https://download.csdn.net/download/weixin_38345163/85093785 ADS仿真LNA例程&#xff1a; https://download.csdn.net/download/weixin_38345163/88306351

Sui上低Gas费为预言机注入强大动力

在当今世界中&#xff0c;大数据推动了许多真正有用的应用发展&#xff0c;预言机是将这些数据引入区块链的手段。然而&#xff0c;通过预言机进行数据调用需要在区块链上进行交易&#xff0c;并支付相关gas费。Sui保持稳定且低廉gas费的能力&#xff0c;使其成为依赖预言机app…

第07章 InnoDB数据存储结构

第07章 InnoDB数据存储结构 1. 数据库的存储结构&#xff1a;页 索引结构给我们提供了高效的索引方式&#xff0c;不过索引信息以及数据记录都保存在文件上的&#xff0c;确切说是存储在页结构中。另一方面&#xff0c;索引是在存储引擎中实现的&#xff0c;MySQL服务器上的存…

企业防盗版/软件防查盗版

有多少公司&#xff0c;至今都无法摆脱被盗版软件支配的恐惧&#xff1f; 其实大多数时候&#xff0c;企业都是被动当了大冤种&#xff0c;因为他们也并不会主动要求员工使用破解软件。实在是架不住有些不懂版权的、心存侥幸的员工私下里使用。只要公司联网&#xff0c;就一定…