算法学习笔记(3)-二分查找

【Python算法系列十】二分查找算法 二分查找,也叫折半查找,是一种适用于顺序存储结构的查找方法。它是一种效率较高的查找方法,时间复杂度为 O(lgn),但它仅能用于有序表中。也就是说,表中的元素需按关键字大小有序排列。 二分查找用左右两个指针来标注查找范围。程序开始时,查找范围是整个线性表,左指针指向第一个元素,右指针指向最后一个元素;每一次循环过后,查找范围都缩小为原先的一半,直到左右指针重叠或者左指针处于右指针的右侧。因为每次缩小一半的范围,所以可以得出二分查找的时间复杂度为 O(lgn)。 ... 阅读详情


一、二分查找法

1.1、简单介绍

二分查找法(binary search)是一种高效的查找算法,当需要在一段有序的数据中(升序或者降序)中查找某个数据时,如在一个形如1,2,3,4,···,99,100的数组中判断60是否存在,最简单的方式就是遍历判断:

for(int i = 0;i < array.length;i ++){
	if(array[i] == 60){
	 	System.out.println(“存在”);
	}
}

对于100个数据来说,最坏的情况就是查找比对100次,但是随着元素的扩充,查找的时间会越来越长,比对的时间也会越来越长,所以这时,出现了二分查找法:
每次都“猜测”一个数据范围段中的中间值,如果这个值比我们需要查询的数大,那么说明我们需要的值在这个中值的左边区域,即将查找的范围缩小的一半,同理,如果这个中值小于我们所需的查询值,那么我们要查的值就在右半部分,通过这种思想,每次查询都能排除掉1/2的数据,这就是二分查找法。

在这里插入图片描述

1.2、简单实现
 public class BinarySearch {

    public static void main(String[] args) {
        int[] arr = {5,13,19,21,37,56,64,75,80,88,92};
        binarySearch(21,arr);
    }

    public static void binarySearch(int key,int[] array){
        int lo = 0;
        int hi = array.length - 1;
        while (lo < hi) {
            int mid = lo + (hi - lo) /2;
            int midValue = array[mid];
            if ( midValue > key) {
                hi = mid - 1;
            } else if (midValue < key) {
                lo = mid + 1;
            } else {
                System.out.println("find\t"+key+"\tin\tindex\t"+i);
            }
        }
    }
}

// find	21	in	index	3

上面的二分查找算法貌似已经可以完成任务了,它快速地找到了21所在的索引为3,但是如果出现多值的情况,譬如21这个值在这个有序数组中存在两个,那么又如何找到它的所有索引呢?

博主想用的方法是"二分查找+小范围遍历",也就是通过二分查找快速地确定某一个key所在的位置,然后在定义由这个key延展开的左右指针去小范围搜索这个key,如果有的话,告诉我们它的位置,这样就可以完成多值条件下的查找了。

1.3、二分查找+小范围搜索
public class BinarySearch {

    public static void main(String[] args) {
        int[] arr = {5,13,19,21,21,21,21,37,56,64,75,80,88,92};
        binarySearch(21,arr);
    }

    public static void binarySearch(int key,int[] array){
        int lo = 0;
        int hi = array.length - 1;
        while (lo < hi) {
            int mid = lo + (hi - lo) /2;
            int midValue = array[mid];
            if ( midValue > key) {
                hi = mid - 1;
            } else if (midValue < key) {
                lo = mid + 1;
            } else {
                //将lo和hi指向key的左右范围内,确定是否只有一个key
                for (int i = mid - 1; i >= 0&& array[i] == key; i--) {
                    System.out.println("find\t"+key+"\tin\tindex\t"+i);
                }

                System.out.println("find\t"+key+"\tin\tindex\t"+mid);

                for (int j = mid + 1; j <= hi&& array[j] == key; j++) {
                    System.out.println("find\t"+key+"\tin\tindex\t"+j);
                }
                return;
            }
        }
    }
}

// find	21	in	index	5
// find	21	in	index	4
// find	21	in	index	3
// find	21	in	index	6
1.4、二分查找的递归实现
public static Integer binarySearch(int[] a, int target, int left, int right) {
        if (left > right) return null;
        int middle = left + (right - left) / 2;
        if (target > a[middle]) {
            //右半部分递归找
            return binarySearch2(a, target, middle + 1, right);
        } else if (target < a[middle]) {
            //左半部分递归找
            return binarySearch2(a, target, left, middle - 1);
        } else {
            return target;
        }
    }

二、题外话:大O表示法

大O表示法是用以估算算法的时间复杂度的一种方法,它用符号O(N)来表示算法执行时间,其中N是一个和元素项相关的表达式的取最高阶,忽略掉了常数项。比如查找长度为10的数组中的某一项时,最多需要查找10次;当长度为100时,最多需要查找100次,假如每一次查找需要消耗时间为k,那么算法执行时间t和数组长度的关系可表示为 t = kn,其中k是常数,n的最高次为1,可不写,那么用大O表示法表示其时间复杂度为O(n);
而二分查找法的时间复杂度可以表示为O(logn),其中n为元素数;
在这里插入图片描述
用大O表示法表示的时间复杂度,O(1)表示的是常数时间操作,这是算法最理想的一种情况,但是绝大多数算法都无法达到这样的效率;二分查找法是时间复杂度为O(logn),算法的执行时间和元素数符合对数增长,是一种很好的情况;而最不理想的情况就是O(n^2)这类的指数型增长了。

在这里插入图片描述

2.1、二分查找法快速估算

使用二分查找法时我们可以发现一些规律,如图
在这里插入图片描述
在这里插入图片描述
即二分查找法的范围r和查找次数s可以用对数函数s = log2(r)来表示,比如在100个数据中查询一个数据吗,最多需要log2(100) <=7次。

算法学习笔记【1】——二分查找 阅读详情

相关推荐

静态表查找--顺序表的查找(有序)--折半查找

静态查找表在查找的过程中不改变表的状态---不插入也不删除,适合不变动或者不经常变动的查找,顺序表可以使有序的也可以是无序的,如果是有序的可以使用折半查找,每查找一次,就把范围缩小一半,如果是无序的就只能从表的一端开始逐一查找了。 本文先用Create_Seq(SSTable &ST,ElemType r[],int n)构造一个无序的静态查找表,然后调用函数void Ascend(SSTabl

滴水藏海 1万+

二分查找(折半查找)

二分查找又称折半查找,它是一种效率较高的查找方法。 折半查找的算法思想是将数列按有序化(递增或递减)排列,查找过程中采用跳跃式方式查找,即先以有序数列的中点位置为比较对象, 如果要找的元素值小于该中点元素,则将待查序列缩小为左半部分,否则为右半部分。通过一次比较,将查找区间缩小一半。 折半查找是一种高效的查找方法。 它可以明显减少比较次数,提高查找效率。但是,折半查找的先决条件是查找表中的数...

weixin_34384557的博客 697

二分查找算法流程图流程图举例

数据结构中简单的二分查找(折半查找)流程图实例

Python实现二分查找

  #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/3/18 18:48 # @Author : baoshan # @Site : # @File : binarySearch.py # @Software: PyCharm Community Edition # 二分查找...

weixin_34258782的博客 219

【效率手册】Kylin-Desktop-V10-SP1 麒麟系统核心组件实战——从入门到精通的6个关键场景

本文针对Kylin-Desktop-V10-SP1麒麟系统用户,通过文件管理、系统监视、设置优化等6个核心场景实战,深度解析如何高效运用系统内置工具解决文件混乱、性能卡顿、外设驱动等实际问题,帮助用户从功能认知跃升至场景化应用,真正释放国产操作系统的生产力潜能。

weixin_29208327的博客 119

从镜头到像素:深入解析Camera、Sensor与V4L2的协同工作流

本文深入解析了摄像头从物理成像到软件控制的完整工作流。详细介绍了镜头、传感器(Sensor)与V4L2框架的协同机制,涵盖光电转换、同步信号、ISP图像处理等核心环节,并通过实战演示了如何使用v4l2-ctl工具进行调试,为嵌入式开发和驱动调试提供系统指南。

weixin_29230805的博客 390

二分查找有序数组

简介 二分查找也称折半查找,它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序储存结构,而且表中元素按关键字有序排列。 从简介可以得知,二分查找要有两个要求,一个是必须采用顺序储存结构,二个是必须按关键字大小有序排序,满足这两个条件的就可以使用二分查找 二分查找使用方法 一个有序数组[1,2,3,4,5,6,8,9,10,13,15,19],要求你找出8的下标,一般想到的都是遍历一遍,然后到8的时候打印8的下标即可,但是这样非常耗时间,所以我们可以使用二分查找。二分查找,也叫折半查找,顾名思义

liuzhenweii的博客 949

蚁群算法(Ant Colony Optimization,ACO)讲解+代码实现

通常情况下,较优的解对应的路径上的信息素会被加强,而较差解对应的信息素则会减少或蒸发。的化学物质,这种物质会在蚂蚁走过的路径上留下痕迹,后续的蚂蚁会根据这些信息素的浓度来选择路径,从而形成一条从蚁巢到食物源的。在求解TSP蚁群算法中,每只蚂蚁相互独立,用于构造不同的路线,蚂蚁之间通过信息素进行交流,合作求解。的过程,该路段经过的蚂蚁越多,信息素留下的就越多,浓度越高,更多的蚂蚁都会选择这个路段。需要注意的是,蚁群算法是一种。(6)计算每只蚂蚁的总距离:遍历每只蚂蚁的路线,累加经过的城市之间的距离。

m0_73804764的博客 1万+

数据结构与算法学习笔记3|数组二分查找和双指针算法

也叫折半查找算法、对数查找算法,是一种用于在有序数组中查找特定元素的高效搜索算法。每一次查找,排除掉一定不存在目标元素的区间,在剩下可能存在目标元素的区间中继续查找。给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。请必须使用时间复杂度为O(log n)的算法。

weixin_45037748的博客 1554

【数据集处理】基于ERA5 气温/湿度数据计算湿球温度并判别湿热浪

【数据集处理】基于ERA5 气温/湿度数据计算湿球温度并判别湿热浪

WW、forever的博客 488

基于 FastAPI + LangGraph + LLM 大语言模型的通用 Agent 多智能体系统架构设计与开发实战、产业应用

FastAPI是一个现代、快速(高性能)的Python Web框架,专门用于构建API。它由Sebastián Ramírez(@tiangolo)创建,基于Starlette(用于Web部分)和Pydantic(用于数据部分)构建。性能优先:FastAPI是当前最快的Python Web框架之一,性能与NodeJS和Go相当。这得益于其基于Starlette的异步架构,能够充分利用Python 3.6+的async/await特性。开发效率。

AI天才研究院 233

python3.0 算法学习笔记(一)二分查找

python3.0 算法学习笔记(一)二分查找 说明 二分查找,是针对有序列表快速查找元素算法 要求 对于查找的对象必须是有序的 代码实现 如果被查找的元素包含在有序list中,则返回index,否则返回空 ...

C_SF_C 201

(十一)随机性与独立性回顾

随机性与独立性回顾

旺旺的碎冰冰~的博客 1018

Coursera_ Algorithms I 学习笔记:Module_3_Analysis_of_Algorithm_Introduction

Coursera_ Algorithms I 学习笔记:Module_3_Analysis_of_Algorithm_Introduction

approximately_的博客 2101

Unreal5从入门到精通之如何在VR中使用3DUI

前面我们讲过《Unreal5从入门到精通之UMG的使用》一般制作游戏时,UI都是添加到屏幕视窗上面的,但是在制作VR时,我们往往需要制作一个3D的UI,放置在场景中,然后使用手柄的射线来和UI进行交互。今天我们就来讲解下,如何在VR中创作和交互3DUI首次操作会感觉好复杂,多多练习,当你熟悉了UE蓝图的操作后会发现,这只是一个常规的蓝图操作而已。祝大家在虚幻的学习过程中非常顺利。希望这篇博客对你有所帮助。

TxNet 1988

PCL 平面点云的凹多边形边界提取【2025最新版】

平面点云的凹多边形边界提取及边界轮廓线绘制。博客长期更新,本文最近更新时间为:2025年1月6日。

点云侠的博客 7185

【算法系列篇】二分查找——这还是你所知道的二分查找算法吗?

二分查找算法的学习:二分查找、在排序数组中查找元素的第⼀个和最后⼀个位置、搜索插⼊位置、x的平方根、⼭峰数组的峰顶、寻找峰值、搜索旋转排序数组中的最⼩值

不能再留遗憾了的博客 4428

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

算法(3)——二分查找

二分查找OJ题目详解

m0_69323023的博客 4311

Statistics and Machine Learning Toolbox

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

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

【基础算法总结】二分查找

二分查找算法是一种十分经典,十分基础的算法。细节最多,最容易写出死循环,但是真正掌握之后,又是最简单的算法。相信大家在之前一定听过"二分查找只用于数组有序的情况下这种说法,其实这是不准确的!!!它的本质是:数据具有二段性。应用场景准确的说是:当数组里的一个数和目标数比较之后,划分出了两段区域(此时具有"二段性"),通过某种规律可以直接舍弃一段区域,在另一段区域查找,周而复始这个操作,直到找到目标数。本篇文章将通过若干道题目进行验证。

2301_77900444的博客 1809

算法思想总结:二分查找算法

二分查找的策略基本上都是去找一个数,对应的有三种模版:正常的二分查找、左区间端点查找、右区间端点查找。

weixin_51142926的博客 2387

算法——二分查找算法

简单来说,"二分"指的是将查找的区间一分为二,通过比较目标值与中间元素的大小关系,确定目标值可能在哪一半区间内,从而缩小查找范围。这个过程不断重复,每次都将当前区间二分,直到找到目标值或确定目标值不存在为止。这种分而治之的策略使得二分查找算法具有较高的效率,时间复杂度为O(log n)。大致图解如下即通过二段性,在每次判断过后可以一次性减少将近一半的数据,然后通过不断的挪移左右区间来筛选出最后的结果。

qq_73201597的博客 3519

【算法图解】 之 [二分查找法] 详解

入门算法学习,看的第一本是深入浅出的《算法图解》一书,本博客是对《算法图解》一书的学习笔记,将书中的分享的算法示例用Python3语言实现。 如果你也想要阅读这本书,百度云盘链接:https://pan.baidu.com/s/1s967vfgEBd1vSrfwVI9Y3g 提取码:【be9k】 或者也可以留言你的邮箱,我将PDF共享给你~ 二分查找 二分查找是一种算法,其输入是一个有序的元...

May女子の博客 4945

二分查找算法上篇

你无需成为谁

X_do_myself的博客 967

二分查找算法

我们如果在循环里面判断,就会需要求middle,这个时候middle就不变化,而nums[middle]是符合nums[middle]>=target的,所以会执行right=middle;左边不一定有峰值,右边一定有峰值,这个时候我们应该让mid往右边去靠近,那只能移动left,这个时候nums[mid]绝对不是是右边的峰值,而nums[mid+1]有可能是右边(不包括i)的峰值,所以我们让left=mid+1即可。当我们的数据量很大的时候,这个right+left的时候,是会溢出的。

2301_80224556的博客 1039

【学习】《算法图解》第一章学习笔记:算法简介与二分查找

《算法图解》第一章学习笔记介绍了算法基础概念,重点讲解了二分查找算法及其Python实现。笔记指出算法是一组解决问题的步骤,强调效率的重要性。二分查找要求数据有序,通过不断缩小搜索范围实现高效查找,时间复杂度为O(log n)。笔记还介绍了大O表示法,用于描述算法的时间复杂度,比较了不同算法的性能差异,如O(n)、O(n²)等。最后强调大O表示法的重要性,为后续学习算法和数据结构奠定基础。

一个普通程序员的成长记录簿 925

算法:二分查找

二分查找算法讲解以及一些相关题目的总结

yanxiao07的博客 1980
上一篇: Java基础(2)-数组介绍
下一篇: 数据结构(1)-栈
BoringRong
BoringRong 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 2万+粉丝 386原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BoringRong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值