无处不在的二分查找

二分查找总结 一、概述 1、定义 二分查找是一种广泛使用的搜索算法,主要用于在有序数组(一般是升序,后面的内容也只是针对升序情况)上查找元素 2、主要思想 二分查找算法背后的主要思想是充分利用元素之间的有序性、以及数组的随机访问特性,每次都与查找区间的中间元素比较大小,根据比较结果不断将查找范围缩小一半(采用分治策略,剪枝?),直到元素被找到,或者,查找区间被缩小为0 3、工作流程 将中间元素... 阅读详情

引入

什么是二分查找?

先来一个简单的游戏,我选定了1-100之间的某个数,你来猜。50?太大了。25?太小了。如此,游戏进行下去,直到你猜中为止。这样,对区间为1-n之间的整数,你可以在log(n)次之内猜中。

在某一给定范围内,查找某个对象,每次查找可以判断该对象与相应位置值的关系。二分查找通过查找当前范围的中间位置来定位,这样每次查找之后,查找的范围都会变为原来的一半。二分查找其实是一种分而治之的思想,将查找的任务分解为两个子空间,每次比较都判断下一个查询的子空间,依次迭代之后,最终达到查询的目的。

 

性能

对比用顺序查找的方法,如从1开始往n逐个猜测,平均需猜测n/2次。

如果n为100万,使用二分查找,只需20次,而顺序查找平均需100万次,可以看出二分查找的强大性能。

关于这种方法快速的实质,在《数学之美番外篇》中,有很生动的探讨,基本idea是,每次查找得到的分支,都是等概率的。

 

用处

二分查找应用范围很广,最常见的当然是有序数组中的元素查找。数学上,求解方程的近似解时,也会用到二分法查找。

在《编程珠玑》”2、9章都有提及。而《编程之美》3.11节“程序改错”中,提到的第一个改错就是二分查找。

 

用法

1.最简单的查找是在有序数组中,查找某个数,返回任意一个满足的索引。

如数组1,5,19,20,31,31,401 中查找31,满足的有2个,则查找返回任意一个位置都可以。

算法设计很简单,使用三个标记:l,u,m;  l代表当前搜索的范围的下界,u代表上届,m为l和u的中值(向下取整)。

迭代过程只需比较m位置的值与x(所查找的值)关系,若 a[m]>x,则x只可能出现在左边的区间,此时只需修改u为m-1;若a[m]<x,则x只可能出现在右边的区间,此时只需修改l的值为m+1;迭代终止条件为l值大于u。

int bisearch_v1(int*a,int n,int x)
{
	int l=0,u=n-1,m;
	while (l<=u)
	{
		m=l+(u-l)/2;//注意 没有使用m=(l+u)/2;防止越界

		if(a[m]==x) 
			return m;
		if (a[m]>x)
			u=m-1;
		else
			l=m+1;
	}
	return -1;
}


2.上述算法有两个问题:

a.每次循环迭代,需要比较两次,有没有更高效的算法?

b. 有多个符号条件的位置时,不能返回特定位置要求。

重新定义问题:在有序数组中,查找某个数,返回一个满足的索引,如有多个位置满足要求,则返回第一个满足的索引。

关键思路: 仍然使用三个标记:l,u,m。设有关系式:a[l]<x<=a[u], 并假设 a[-1]<x,a[n]>=x。其中l 代表检索范围内,已检索的小于x的最大索引,初始值为-1;u代表检索范围内,已检索的大于或等于x的最小索引。迭代终止条件为l+1==u,此时l 指向的是有序数组中,小于x的最大索引,而u为大于或等于x的最小索引。只需检测u,a[u]与x的关系即可。

int bisearch_v2(int *a,int n,int x)
{//注意对比1中 l,u的初始值,迭代终止条件,以及l,u的修改方法
	int l=-1,u=n,m;
	while (l+1!=u)
	{
		m=l+(u-l)/2;
		if (a[m]<x)
			l=m;
		else
			u=m;		
	}
	if(u!=n&&a[u]==x)
		return u;
	else
		return -1;
}

3.类似2中描述,如《编程之美》所提出的 ,找出一个有序(字典序)字符串数组中,值等于字符串v的元素的序号,如果有多个元素满足这个条件,则返回其中最大的序号。

可用2中分析的方法来解。

同时该书中提到多个二分查找类似的问题,摘录如下:

a.给定一个有序(不降序)数组arr,求任意一个i使得arr[i] 等于v,不存在则返回-1

b.给定一个有序(不降序)数组arr,求最小的i使得arr[i] 等于v,不存在则返回-1

c.给定一个有序(不降序)数组arr,求最大的i使得arr[i] 等于v,不存在则返回-1

d.给定一个有序(不降序)数组arr,求最大的i使得arr[i] 小于v,不存在则返回-1

e.给定一个有序(不降序)数组arr,求最小的i使得arr[i] 大于v,不存在则返回-1

有兴趣的朋友可以思考下。

二分查找算法 摘要 二分查找,一个很经典的算法。但是真正理解透彻这个算法却不容易。下面记载一点自己学习二分查找的心得。 参考 正文: 二分查找有N多种写法,有各种各样的形式,选一种合适自己,自己能够理解记住的才是最好的。下面分享一个我比较赞的版本。 对于最最最原始的二分查找,即给出一个Key,查找出key值的索引号。 注意注意注意!!最经典的二分查找对返回来的索引号没有任何要求,只要其对应的值是... 阅读详情

相关推荐

操作系统原理:【优麒麟】linux内核添加系统调用

在底端添加如下代码。

Joyce_zz的博客 2709

一文看懂二分查找

二分查找原理 二分查找的原理不难理解,即在一个有序数组中,每次将数组中间值与目标值进行比较,从而判断目标值在中间值的左边还是右边。 由于每次可排除一半的数,因此二分查找的时间复杂度为log2n。对于100万个有序数据,利用二分查找仅需搜索20次,效率非常高。mysql的B+树叶子节点的数据查找,用的就是二分查找。 代码编写 中间值 第一次写二分查找的代码时,都会有一个疑惑,那就是如果数组的个数是奇数和偶数时,中间值要不要分别处理?再加上数组的起始值是从0开始,相信当你仔细去区分时,十有八九会被绕晕。我们完全

weixin_46374887的博客 1025

point transformer v3结构

分割结构: embedding->enc->dec embedding->enc0->enc1->enc2->enc3->enc4->dec3->dec2->dec1->dec0 embedding ->block0->block1 ->dow->block0->block1 ->dow->block0->block1 ->dow->block0->block1-&gt

weixin_45625419的博客 581

设计算法统计A中位于区间(L,U)的所有x的个数(用递归和分治来做)

题目:设有序数组A有n个数,给定选取其中的两个元素L和U,L<U,设计算法统计A中满足L<x<u的所有x的个数(用递归和分治来做) 思想: 二分查找法结合递归思想,找到左右边界的下标相减即可。 代码展示: #include <stdio.h> #include <stdlib.h> /* * 题目:设有序数组A有n个数,给定选取其中的两个元素L和U,L...

qq_39690007的博客 1129

手把手教你配置SAP PP供应区域(Supply Area):实现线边仓精准发料与物料流优化

本文详细解析了SAP PP供应区域(Supply Area)的配置方法,帮助企业实现线边仓精准发料与物料流优化。通过三级优先级逻辑和四步配置法,系统可自动识别最优组件来源位置,显著提升生产订单处理效率和库存准确率。文章还提供了典型问题解决方案和性能优化技巧,适用于离散制造和重复制造场景。

weixin_29275257的博客 432

nbiot和2g_浅谈NBIOT

一、什么是NBIOT?1、概念窄带物联网(Narrow Band Internet of Things, NB-IoT),NB-IoT构建于蜂窝网络,只消耗大约180KHz的带宽,使用License频段,可采取带内、保护带或独立载波等三种部署方式,与现有网络共存。可直接部署于GSM网络、UMTS网络或LTE网络,以降低部署成本、实现平滑升级。2、NBIOT的特点和目标(1)超强覆盖:相对GPRS来...

weixin_39534100的博客 1704

二分查找之红蓝二分查找

/ 目标值在左半部分} else {left = mid;// 目标值在右半部分left : -1;// 返回最后一个满足条件的值的索引。

xiaoxie8023的博客 2328

Oracle19c SYSAUX表空间爆满?手把手教你清理SM/ADVISOR和AUDSYS占用(附完整SQL)

本文详细解析了Oracle19c中SYSAUX表空间爆满的常见原因及解决方案,重点针对SM/ADVISOR和AUDSYS组件的空间占用问题提供了完整的SQL清理脚本。通过诊断查询、空间清理和预防性维护策略,帮助DBA有效管理SYSAUX表空间,确保数据库稳定运行。

weixin_28338005的博客 236

详解二分查找

一.为什么要使用二分查找 当有一个排好顺序的数组,我们需要知道我们要找的值是否在当前数组中,那么我们就需要自己实现一个查找的方法来进行实现,那么如果我们找的数在最后一个位置n处,假设这个n非常大,那么我们要是一次一次进行比较的话就要比较n次,这样就会显得非常慢,那么有没有一种相较于普通查找速度更快的方法吗,那就是二分查找。 二.二分查找的解释 二分查找:也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。

weixin_47651920的博客 5939

车载以太网:PHY(物理层)介绍

本文以TJA1101芯片为实例介绍了车载以太网PHY(物理层)组成。

kevin1499的博客 6231

32位快速加法器设计

32位快速加法器设计

好好学习,天天向上 3289

二分查找最坏查找次数_二分查找 事半功倍

前言:“Simplicity is the soul of efficiency.”简洁是效率的灵魂。-- Enda Kenny, TaoiseachYou clicked onthe third article written by ADOSCIE.你激动的点开了ADOSCIE的第三篇文章。But you realized that you aren’t familiar with ...

weixin_34294809的博客 2227

【Unity】 预制体Prefab使用说明

在 Unity 中,Prefab 是一个可以预先制作并重复使用的 GameObject 或组件集合,Prefab 中的 GameObject 可以有子对象和其他组件。

灵境引路人 2849

二分查找

二分查找顾名思义,平分成两份查找(以网易云课堂 第六周作业为例,使用Python语言) 两点入门二分查找: a. 猜测的值 = 中间值 =(low+high)/2 —— 二分的意义 b. 中间值实际值,high = 中间值-1 一些实例: 1.定义一个 prime() 函数求整数 n 以内(不包括n)的所有素数(1不是素数),并返回一个按照升序排列的素数列表。使用递归来实现一个二

关于一个技术小白的…… 1407

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

c++二分查找

由于此时只剩下两个数了,所以我们不再二分了,直接判断A[8]是否等于17,或者A[9]是否等于17即可。//表示要在A[1]至A[N]范围查找x。因为我们要查找的数是3,小于A[mid],所以我们下次要在A[L]至A[mid]范围内查找,//查询数组A是否包含x。因为要查找的数是17,大于A[5],所以我们应该在A[5]至A[10]这一段查找,令L=1, R=10, 表示我们用在A[1],A[2],...A[10]里面查找。1、当要查找的数小于A[1]或者大于A[N],返回"no",否则进入二分查找过程。

浪子回头 1733

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

算法——二分查找

算法——二分查找一、二分查找的框架二、基本二分查找的两种写法1.定义target在闭区间[left,right]2.定义target在左闭右开区间[left,right)三、寻找边界的二分查找1.寻找左侧边界的二分查找写法1写法22.寻找右侧边界的二分查找写法1写法2题目:leetcode704.二分查找leetcode35.搜索插入位置思路1.暴力解法2.二分法 一、二分查找的框架 使用条件: 数组为有序数组 数组中无重复元素(一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的) int bi

weixin_61015911的博客 1371

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

一看就懂的二分查找

无处不在的二分思想 二分查找是一个简单而且容易理解的算法。在实际生活中也有很多的时候能够用到。比如说简单的猜字游戏,在一组卡片中,有0到99个数字,你可以写出一个你想要的数字,之后在里面抽取,抽取的结果由主持人进行告知,大的时候可以往左边抽取,小的时候往右边抽取。假设选的数字是23,也仅仅只需要七次就可以抽取到。但是如果要是一个一个遍历的话,速度上就会慢很多,所以这种思想就叫做二分查找。 看一张图 现在来看一个例子,假设我们有10个订单,订单金额分别是:8,11,19,23,27,33,55,67

weixin_46272350的博客 741

简单二分查找、复杂二分查找与跳表

1.查找的分类 1.1 查找表 用于查找的数据集合称之为查找表,它由同一类型的数据元素(或记录)组成,可以是一个数组或者链表等数据结构。对查找表经常进行的操作一般有四种: 1.查询某个特定的数据是否在查找表中。 2.检索满足条件的某个特定的数据元素的各种属性。 3.在查找表中插入一个数据元素。 4.从查找表中删除某个数据元素。 1.2 静态查找表与动态查找表 如果一个查找表的操作只涉及到1和2的操作,则无需动态地修改查找表,此类查找表称之为静态查找表,反之称之为动态查找表。 适合静态查找表的查找方法有:顺序

编程使我快乐 937

Leetcode之二分查找

向后看一眼对于这种情况,当我们通过二分查找,找到第一个等于target的元素的时候,需要看一下mid右边的值是否也等于target,如果是,则我们需要继续对[mid+1,high]进行二分查找,如果不是,则说明mid就是我们要找的元素。题目链接解题思路参考上面的二分查找的变形,我们可以分别找到第一个大于等于target的下标和最后一个等于target的下标,然后返回这两个下标即可。

古承风的博客 1041

【二分查找】二分查找总结

1、梳理二分查找: (1)while (left < right) 退出循环的时候有 left == right 成立,因此无需考虑返回 left 还是 right; (2)始终思考下一轮搜索区间是什么,如果是 [mid, right] 就对应 left = mid ,如果是 [left, mid - 1] 就对应 right = mid - 1,是保留 mid 还是 +1+1、-1−1 就在这样的思考中完成; (3)从一个元素什么时候不是解开始考虑下一轮搜索区间是什么 ,把区间分为 2 个部

StudyWinter的博客 609
上一篇: 一道有意思的2012搜狗笔试题
下一篇: 阿里巴巴2012-10-9 几道笔试题
ClockWiser
博客等级 码龄14年 2粉丝 7原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值