算法——二分查找

【C语言】二分查找 在有序表中,每次都取中间元素作为比较的对象。 如果给中间值与给定值相等,则查找成功,返回该元素的下标/索引; 如果中间值大于给定值,则在中间值的右半区间继续查找; 如果中间值小于给定值,则在中间值的左半区间继续查找;........................ 阅读详情

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

二分查找算法仅适用于有序序列,它只能用在升序序列或者降序序列中查找目标元素。

一、工作原理

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

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

二、性质

(1)时间复杂度

二分查找的最优时间复杂度为O(1) 。

二分查找的平均时间复杂度和最坏时间复杂度均为 O(logn)。因为在二分搜索过程中,算法每次都把查询的区间减半,所以对于一个长度为n 的数组,至多会进行 O(logn) 次查找。

(2)空间复杂度

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

递归(无尾调用消除)版本的二分查找的空间复杂度为O(logn) 。

三、二分查找算法原理

(1)若待查序列为空,则返回-1,并退出算法;

(2)若待查序列不为空,则将它的中间元素与目标数值进行比较,判断是否相等;

(3)若相等,则返回中间元素索引,并退出算法;此时已查找成功。

(4)若不相等,则比较中间元素与目标数值的大小;

(5)若中间元素 > 目标数值,则将当前序列的前半部分作为新的待查序列;

(6)若中间元素 < 目标数值,则将当前序列的后半部分作为新的待查序列;

(7)在新的序列上重新从第(1)步开始查找。

基本步骤

  1. 初始化:设定两个指针,left 和 right,分别指向数组的起始和末尾。
  2. 计算中间位置:计算中间位置 mid,mid = left + (right - left) // 2。
  3. 比较:
    • 如果 arr[mid] 等于目标值 target,则查找成功,返回 mid。
    • 如果 arr[mid] 小于目标值 target,则目标值在右半部分,更新 left = mid + 1。
    • 如果 arr[mid] 大于目标值 target,则目标值在左半部分,更新 right = mid - 1。
  4. 重复:重复步骤2和步骤3,直到 left 大于 right,此时查找失败,返回 -1。

四、以在升序序列中查找目标元素为例,二分查找算法的实现思路是:

(1)初始状态下,将整个序列作为搜索区域(假设为 [B, E]);

(2)找到搜索区域内的中间元素(假设所在位置为 M),和目标元素进行比对。如果相等,则搜索成功;如果中间元素大于目标元素,表明目标元素位于中间元素的左侧,将 [B, M-1] 作为新的搜素区域;反之,若中间元素小于目标元素,表明目标元素位于中间元素的右侧,将 [M+1, E] 作为新的搜素区域;

(3)重复执行第二步,直至找到目标元素。如果搜索区域无法再缩小,且区域内不包含任何元素,表明整个序列中没有目标元素,查找失败。

五、实例讲解

在下图所示的升序序列中查找元素 31。

二分查找实例

二分查找算法的具体实现过程为:

(1)初始状态下,搜索区域是整个序列。找到搜索区域内的中间元素。指定区域内中间元素的位置可以套用如下公式求出:

Mid = ⌊ Begin + (End - Begin) / 2 ⌋

End 表示搜索区域内最后一个元素所在位置,Begin 表示搜索区域内第一个元素所在的位置,Mid 表示中间元素所在的位置。

所有元素的位置分别用 0~9 表示,中间元素的位置为 ⌊ 0 + (9 - 0) / 2 ⌋ = 4,如下图所示:

二分查找实例

中间元素 27 < 31,可以断定 [0, 4] 区域内绝对没有 31,目标元素只可能位于 [5, 9] 区域内,如下图所示:

二分查找实例

(2)在 [5, 9] 区域内,中间元素的位置为 ⌊ 5 + (9 - 5) / 2 ⌋ = 7,如下图所示:

二分查找实例

中间元素 35 > 31,可以断定 [7, 9] 区域内绝对没有 31,目标元素只可能位于 [5,6] 中,如下图所示:

二分查找实例

(3)在 [5, 6] 区域内,中间元素的位置为 ⌊ 5 + (6- 5) / 2 ⌋ = 5,中间元素就是 31,成功找到目标元素。

六、代码展示

 Python

def binary_search(arr, target):
    left, right = 0, len(arr) - 1
    
    while left <= right:
        mid = left + (right - left) // 2
        
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    
    return -1

# 示例
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
target = 7
result = binary_search(arr, target)

if result != -1:
    print(f"元素 {target} 在数组中的索引为: {result}")
else:
    print(f"元素 {target} 不在数组中")

C 

#include <stdio.h>
//实现二分查找算法,ele 表示要查找的目标元素,[p,q] 指定查找区域
int binary_search(int *arr,int p,int q,int ele) {
    int mid = 0;
    //如果[p,q] 不存在,返回 -1
    if (p > q) {
        return -1;
    }
    // 找到中间元素所在的位置
    mid = p + (q - p) / 2;
    //递归的出口
    if (ele == arr[mid]) {
        return mid;
    }
    //比较 ele 和 arr[mid] 的值,缩小 ele 可能存在的区域
    if (ele < arr[mid]) {
        //新的搜索区域为 [p,mid-1]
        return binary_search(arr, p, mid - 1, ele);
    }
    else {
        //新的搜索区域为 [mid+1,q]
        return binary_search(arr, mid + 1, q, ele);
    }
}
 
int main()
{
    int arr[10] = { 10,14,19,26,27,31,33,35,42,44 };
    //输出二叉查找元素 31 所在位置的下标
    printf("%d", binary_search(arr, 0, 9, 31));
    return 0;
}

Java

public class Demo {
    // 实现二分查找算法,ele 表示要查找的目标元素,[p,q] 指定查找区域
    public static int binary_search(int[] arr, int p, int q, int ele) {
        // 如果[p,q] 不存在,返回 -1
        if (p > q) {
            return -1;
        }
        // 找到中间元素所在的位置
        int mid = p + (q - p) / 2;
        // 递归的出口
        if (ele == arr[mid]) {
            return mid;
        }
        // 比较 ele 和 arr[mid] 的值,缩小 ele 可能存在的区域
        if (ele < arr[mid]) {
            // 新的搜索区域为 [p,mid-1]
            return binary_search(arr, p, mid - 1, ele);
        } else {
            // 新的搜索区域为 [mid+1,q]
            return binary_search(arr, mid + 1, q, ele);
        }
    }
 
    public static void main(String[] args) {
        int[] arr = new int[] { 10, 14, 19, 26, 27, 31, 33, 35, 42, 44 };
        // 输出二叉查找元素 31 所在位置的下标
        int add = binary_search(arr, 0, 9, 31);
        System.out.print(add);
    }
}

【二分查找】详细图解 二分查找法详解 阅读详情

相关推荐

【查找算法】二分查找

【查找算法】二分查找

suiyishiguang的博客 2918

二分查找--图文详解

二分查找也称折半查找,是在一组有序(升序/降序)的数据中查找一个元素,它是一种效率较高的查找方法。

iLoyo_的博客 3万+

【Python算法系列十】二分查找算法

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

m0_70372647的博客 6755

二分查找(折半查找)

二分查找是一种算法,其输入是一个有序的元素列表(必须是有序的),如果查找的元素包含在列表中,二分查找返回其位置,否则返回NULL 比如说有一个1-100的数字,我随机的选择其中一个数字(假设为60),你需要以最少的次数猜到我所选择的数字,每次猜测后,我会告诉你大了,小了,对了。 假设你第一次从1开始猜,小了 第二次:2 小了 第三次:3 小了 …… 第五十九次:59小了 ...

zmeilin的博客 15万+

二分查找算法

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

SCUT_Sam 5007

AirSim安装和地图加载

详细教程如何安装AirSim并加载地图

fegxg的博客 3033

优选算法《二分查找》

在之前的学习当中我们已经初步了解过了二分查找的整体逻辑以及二分查找,接下来我们在本篇当中将系统的来学习二分查找的使用方式以及在什么情况下可以使用二分查找。在之前的学习当中我们了解到的二分查找是要求在有序的数组当中当数组元素有序时才能使用,但是其实这只是二分查找最朴素的使用场景,接下来我们将学习更多的二分查找的使用场景。相信通过被本章的学习之后你会有所收获,一起加油吧!!!

mljy.博客 2496

基于Python爬虫的新闻热点分析与挖掘

本文介绍了基于Python爬虫的新闻热点分析与挖掘方法,主要包括数据收集、预处理、热点分析和可视化四个部分。首先通过爬虫抓取新浪新闻数据,利用文本清洗和存储技术进行数据预处理;接着采用TF-IDF和LDA算法进行关键词提取与主题建模;最后通过词云图和主题分布图实现数据可视化。该方法能有效识别新闻热点,为信息筛选和决策提供支持。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1544

算法——二分查找算法

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

qq_73201597的博客 3504

单细胞分析避坑指南:SCTransform和Harmony参数设置详解

本文深入解析了单细胞分析中SCTransform标准化与Harmony批次校正的关键参数设置。针对10x Genomics等数据,详细探讨了如何通过调整`vars.to.regress`、`theta`等核心参数,在有效去除技术噪音的同时,避免过度校正以保留关键的生物学差异,从而提升分析结果的可靠性与可解释性。

weixin_29053073的博客 608

ROS 入门教程:小乌龟仿真器和基础操作

小乌龟仿真器和ros基础操作

zlflll的博客 4125

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

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

2301_77900444的博客 1808

海思方案定制hi3531dv200/SS528 DVR方案解析:从硬件选型到编解码实战应用

海思方案,Hi3518EV100,Hi3518CV100,Hi3515CV100,Hi3516CV100,Hi3516ECV100,Hi3516D,Hi3516A,Hi3519,Hi3520D,Hi3521A,Hi3535,Hi3531,Hi3536,Hi3536C,Hi3536D,Hi3518EV200,Hi3518EV201,Hi3520DV200,Hi3516CV200,Hi3516CV300,Hi3516AV200,Hi3520DV300,Hi3519V101,sd3403,hi3519av200

1585

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

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

weixin_51142926的博客 2387

Kotlin原生AI Agent框架Koog:为JVM开发者打造类型安全、企业级智能体开发方案

AI Agent作为当前人工智能应用开发的核心范式,通过赋予大语言模型(LLM)自主规划、工具调用和环境交互能力,正在重塑软件智能化进程。其技术原理基于智能体架构,通过提示工程、函数调用和记忆机制,将LLM从单纯的文本生成器转变为能够执行复杂任务的工作流引擎。这一技术价值在于显著降低了构建智能应用的开发门槛,同时保持了高度的灵活性和可扩展性。在实际应用场景中,AI Agent广泛落地于智能客服、代码助手、数据分析自动化等领域,成为连接大模型能力与具体业务需求的关键桥梁。本文聚焦的Koog框架,正是针对JVM

weixin_42594419的博客 395

rk3399 hdmi HDCP key烧录

1.key转换 使用 hdcp\ProvisioningTool_20170526\KeyConverterV2.02 目录下的KeyConvertor.exe工具将1.4key进行转换 转换后得到 TX00000001.skf 文件,将 TX00000001.skf 文件烧录到开发板上,烧录方式: 打开文件 hdcp\ProvisioningTool_20170526\ProvisioningTool20170526\ProvisioningTool.exe 选择烧录方式与烧录路...

qq_32645109的博客 3857

算法【Java】—— 二分查找

介绍二分查找算法,使用Java 实现

熵减玩家 4637

[数学建模][2012年A国赛模拟] 3. 葡萄酒的评价

暑期学校数学建模培训第三次模拟:2012年国赛A题,一道完全统计方面的题目。据老师反映当年有位老师所带领小组取得“全国10佳优秀论文奖”,我们大组搞统计的老师建模能力不行,但其统计理论非常扎实,在此期间给予我们非常大的帮助,十分感谢老师的倾囊相授。我们小组的定位也不在统计方向,主攻物理建模及优化模型,故本次模拟就用SPSS软件简单做了下,还是学到了多元统计的许多知识,达到了本次训练的目的。 ...

Y-puyu 的博客 3万+

【算法】二分查找

本文总结了二分查找的特点、使用条件、和时间复杂度的分析,并且还将二分进行总结成三种情况,分别是朴素二分、查找左边界的二分和查找右边界的二分三种情况。通过若干到例题进行强化算法思维。

2302_80475369的博客 1841

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

jre9下载 jdk9

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

数组的二分查找算法

C语言:分支、循环结构语法基础巩固

qq_73270870的博客 2089

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

详解二分查找算法

1、 详解二分查找算法 我周围的人几乎都认为二分查找很简单,但事实真的如此吗?二分查找真的很简单吗?并不简单。看看 Knuth 大佬(发明 KMP 算法的那位)怎么说的: Although the basic idea of binary search is comparatively straightforward, the details can be surprisingly tricky... 这句话可以这样理解:思路很简单,细节是魔鬼。 本文就来探究几个最常用的二分查找场景:寻找一个数、寻找左

weixin_39126199的博客 1280

Statistics and Machine Learning Toolbox

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

二分查找(算法)

主要使用场景:在有序数组中找到一个期望的对象算法模板:1:定义 left ,right 指针,分别指向数组的左右区间。2: 找到待查找区间的中间点 mid ,找到之后分三种情况讨论:i. arr[mid] == 查找值说明正好找到,返回 mid 的值ii.arr[mid]>查找值,说明 [mid, right] 这段区间都是⼤于查找值的,因此舍去右边区间,在左边 [left, mid -1] 的区间继续查找,即让 right = mid - 1 ,然后重复 2 过程;

2301_81831423的博客 1720

算法 二分查找算法

题目:本题要求实现二分查找算法。 函数接口定义: Position BinarySearch( List L, ElementType X ); 其中List结构定义如下: typedef int Position; typedef struct LNode *List; struct LNode { ElementType Data[MAXSIZE]; Positi...

Dezeming的博客 7822
上一篇: 算法基础——递归
下一篇: API 接口如何确保数据的安全?
夏子曦
夏子曦 优质创作者: 产品设计技术领域 优质创作者: 产品设计技术领域
博客等级 码龄15年 8289粉丝 427原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值