首页 > 其他分享 >整数二分查找的实现

整数二分查找的实现

时间:2024-05-26 21:30:12浏览次数:17  
标签:二分 int 复杂度 mid 整数 查找

引入

        在一个有序数组中,如果我们想查找某一元素,朴素做法就是从前往后枚举,时间复杂度会达到O\left ( n \right )。但是因为此数组是有序的,所以就可以通过这个性质,使用二分查找实现,可以使时间复杂度降到O\left ( log_{2}n \right )

        下面我们就来讲整数二分查找的实现。

定义

        二分查找(binary search),也称折半搜索(half-interval search)、对数搜索(logarithmic search),是用来在一个有序数组中查找某一元素的算法。

过程

        整数二分查找的思路是这样的:假设目标值在闭区间\left [ l,r \right ]中, 每次将区间长度缩小一半,当l=r时,我们就找到了目标值。

        以在一个升序数组中查找一个数为例。

        它每次考察数组当前部分的中间元素,如果中间元素刚好是要找的,就结束搜索过程;如果中间元素小于所查找的值,那么左侧的只会更小,不会有所查找的元素,只需到右侧查找;如果中间元素大于所查找的值同理,只需到左侧查找。

        我们通常想到二分查找就会想到单调性,认为二分查找只能用于具有单调性的题目。其实不然,只要一个题目具有二段性,二分查找就有用武之地。

Q:什么是单调性呢?

A:单调性通俗点说,就是元素有序,即一个升序或降序的数组。

Q:那什么又是二段性呢?

A:二段性是指对某一范围内的数据,存在一个临界点,使得临界点某一侧的所有数据都满足某一性质,另一侧的所有数据都不满足这一性质,就称这一范围内的数据具有二段性。

        我们可以从中看出,二分查找的本质不在于单调性,而是二段性!

        其实,整数二分查找比浮点数二分查找要复杂得多,浮点数二分查找无需考虑边界,而整数二分查找在代码实现上还要判断加1减1。

        所以,整数二分查找如果写之前不考虑好想要查找的是什么,十有八九会是死循环或者查找错误,就算侥幸写对了也只是运气好而已!

性质

        时间复杂度

        二分查找的平均与坏时间复杂度均为O\left ( log_{2}n \right ),最优时间复杂度为O\left ( 1 \right )

        空间复杂度

        二分查找的空间复杂度为O\left ( 1 \right )(迭代版本)。

代码

        下面给出两种整数二分查找函数的实现:

bool check(int x){

}

int bsearch_1(int l,int r){
	while(l<r){
		int mid=l+r>>1;
		if(check(mid))
			r=mid;
		else
			l=mid+1;
	}
	return l;
}

int bsearch_2(int l,int r){
	while(l<r){
		int mid=l+r+1>>1;
		if(check(mid))
			l=mid;
		else
			r=mid-1;
	}
	return l;
}
        代码解释

        check()函数的作用是检查x是否满足某种性质;bsearch_1()函数的作用是区间[l,r]被划分成[l,mid]和[mid+1,r]时使用(即查找左边界);bsearch_2()函数的作用是区间[l,r]被划分成[l,mid-1]和[mid,r]时使用(即查找右边界)。

        两种整数二分查找函数的区别

        这两种整数二分查找函数有什么区别呢?

        第一种(bsearch_1),查找左边界:当我们将区间\left [ l,r \right ]划分成\left [ l,mid \right ]\left [ mid+1,r \right ]时,其更新操作是r=mid或者l=mid+1,计算mid时不需要加1

        第二种(bsearch_2),查找右边界:当我们将区间\left [ l,r \right ]划分成\left [ l,mid-1 \right ]\left [ mid,r \right ]时,其更新操作是r=mid-1或者l=mid,计算mid时需要加1

        注意,两种整数二分查找中的加1减1不要搞混了,什么时候加,什么时候减,什么时候不写要明确,不然会产生死循环!

        两种整数二分查找函数的应用

        例如数组1 2 2 3 3 3 4,如果你想查找数组中的第一个3(红色),就需要用第一种二分查找(查找左边界);如果你想查找数组中的最后一个3(绿色),就需要用第二种二分查找(查找右边界)。


上一篇-求逆序对问题的实现    C++算法基础专栏文章    下一篇-浮点数二分查找的实现


每周六更新一篇文章,内容一般是自己总结的经验或是在其他网站上整理的优质内容

点个赞,关注一下呗~

标签:二分,int,复杂度,mid,整数,查找
From: https://blog.csdn.net/wyuchen123/article/details/137417788

相关文章

  • 算法刷题笔记 数的范围(C++实现)(二分法重要例题)
    文章目录题目描述题目思路题目代码(C++)题目感想题目描述给定一个按照升序排列的长度为n的整数数组,以及q个查询。对于每个查询,返回一个元素k的起始位置和终止位置(位置从0开始计数)。如果数组中不存在该元素,则返回-1-1。输入格式:第一行包含整数n和q,表示数组长度和询......
  • C语言---求一个整数存储在内存中的二进制中1的个数--3种方法
    //编写代码实现:求一个整数存储在内存中的二进制中1的个数//第一种写法/*intcount_bit_one(unsignedintn){intcount=0;while(n)//除到最后余数是0,那么这个循环就结束了{//这个题就是可以想成求15的二进制的过程//每次都除以2,余数为1的时候就......
  • YOLOv10 | 手把手教你利用yolov10训练自己数据集(含环境搭建 + 参数解析 + 数据集查找
    一、前言本文内含YOLOv10网络结构图+各个创新模块手撕结构图+训练教程+推理教程+  参数解析+环境搭建+数据集获取等一些有关YOLOv10的内容!目录一、前言 二、整体网络结构图 三、空间-通道分离下采样3.1SCDown介绍 3.2C2fUIB介绍3.3PSA介绍4.4更......
  • 复习递归------拆开了输出整数
    问题1:题目概述    这次带来的例题是一道简单题,题目概述如下:     题目要求输入一个整数n,然后从高位到低位输出每位的数字,假设我输入123,则输出必须为123。就是那么简单(数字之间用空格分开)。问题2:思路     我们之前说过递归二要素是停止条件和规......
  • 数据结构与算法学习(05)查找(2)索引——BUAA
    文章目录查找(2)——索引介绍索引的基本概念稠密索引非稠密索引——分块索引多级索引查找(2)——索引介绍本文为查找第二部分,主要是整理了本人上课时讲的内容索引的基本概念索引:记录关键字值与记录的存储位置之间的对应关系索引文件:由基本数据与索引表两部分组成的......
  • 数据结构与算法学习(07)查找(4)散列、哈希、字典——BUAA
    文章目录查找(4)——散列(Hash)字典介绍散列函数的构造方法直接地址法数字分析法平方取中法叠加法移位叠加法折叠叠加法基数转换法除留余数法随机数法一些好的哈希函数**针对字符串好的哈希函数冲突的处理方法开放地址法线性探测二次探测伪随机特点再散列法链接地址法代......
  • 数据结构与算法学习(06)查找(3)Trie树(C语言)——BUAA
    文章目录查找(3)——Trie树(C语言)介绍结构实现典型应用(字典树)代码实现优势查找(3)——Trie树(C语言)介绍本文为查找第三部分,主要是整理了本人上课时讲的内容,并给出了C语言代码实现结构实现键值由固定的字符序列组成(如数字或字母),如Huffman码、英文单词;对应结点的分层标记......
  • 如何求出n之前的所有数满足位数和整数当前数?
    见题:E-DigitSumDivisible(atcoder.jp)P4127[AHOI2009]同类分布-洛谷|计算机科学教育新生态(luogu.com.cn)考虑数位动规,设方程$dp[i][j][k][l]$为状态:$i$:搜到了第$i$位(倒着枚举,也就是指$i$到最高位都填完了)。$j$:表示当前的数位总和$k$:表示当前的数......
  • 整数与浮点数在内存中的存储
    整形数据类型的存储(通常存的是二进制的补码)大端(存储)模式:是指数据的低位字节内容保存在内存的高地址处,而数据的高位字节内容,存储在内存的低地址处。小端(存储)模式:是指数据的低位字节内容保存在内存的低地址处,而数据的高位字节内容,存储在内存的高地址处。 判断高低地址:int......
  • 二分查找法-I
    描述请实现无重复数字的升序数组的二分查找给定一个元素升序的、无重复数字的整型数组nums 和一个目标值target ,写一个函数搜索nums 中的target,如果目标值存在返回下标(下标从0开始),否则返回-1数据范围:0≤len(nums)≤2×1050≤len(nums)≤2×105, 数组中任意值......