二分查找【算法 09】

news2024/12/25 12:42:54

二分查找算法详解

请添加图片描述

二分查找(Binary Search)是一种高效的查找算法,前提是数据必须是有序的。相比于线性查找,二分查找的时间复杂度从 O(n) 降低到了 O(log n),适合处理大规模的数据查找问题。本文将详细介绍二分查找的原理、实现以及其时间复杂度分析。


1. 二分查找的基本原理

二分查找的核心思想是 “分而治之”。它每次通过将查找范围缩小一半,逐步接近目标值。

步骤如下:

  1. 将查找范围的左右边界分别设为 lowhigh
  2. 计算中间索引 midmid = (low + high) / 2
  3. 比较目标值与 mid 位置的值:
    • 如果目标值等于中间值,查找成功,返回索引。
    • 如果目标值小于中间值,将 high 更新为 mid - 1,查找范围缩小为左半部分。
    • 如果目标值大于中间值,将 low 更新为 mid + 1,查找范围缩小为右半部分。
  4. 重复上述步骤,直到 low > high,查找结束。如果没有找到,返回 -1 表示目标不存在。

2. 二分查找的代码实现

以下是用 C 语言实现的二分查找算法:

#include <stdio.h>

int binarySearch(int arr[], int size, int target) {
    int low = 0;
    int high = size - 1;

    while (low <= high) {
        int mid = low + (high - low) / 2;

        // 检查中间值是否为目标值
        if (arr[mid] == target)
            return mid;

        // 如果目标值小于中间值,缩小查找范围到左半部分
        if (arr[mid] > target)
            high = mid - 1;
        // 否则缩小查找范围到右半部分
        else
            low = mid + 1;
    }

    // 如果找不到目标值,返回 -1
    return -1;
}

int main() {
    int arr[] = {2, 3, 4, 10, 40};
    int size = sizeof(arr) / sizeof(arr[0]);
    int target = 10;
    int result = binarySearch(arr, size, target);
    if (result == -1)
        printf("Element is not present in array\n");
    else
        printf("Element is present at index %d\n", result);
    return 0;
}

代码说明:

  • lowhigh 分别表示查找的范围。
  • mid 用于找到中间元素,并根据该元素与目标值的比较结果决定查找范围的缩小方向。
  • 算法的时间复杂度为 O(log n),因为每次查找都会将查找空间减半。

3. 二分查找的递归实现

除了迭代实现外,二分查找还可以使用递归方式实现:

int binarySearchRecursive(int arr[], int low, int high, int target) {
    if (low <= high) {
        int mid = low + (high - low) / 2;

        // 检查中间值是否为目标值
        if (arr[mid] == target)
            return mid;

        // 如果目标值小于中间值,递归搜索左半部分
        if (arr[mid] > target)
            return binarySearchRecursive(arr, low, mid - 1, target);

        // 否则递归搜索右半部分
        return binarySearchRecursive(arr, mid + 1, high, target);
    }

    // 如果找不到目标值,返回 -1
    return -1;
}

int main() {
    int arr[] = {2, 3, 4, 10, 40};
    int size = sizeof(arr) / sizeof(arr[0]);
    int target = 10;
    int result = binarySearchRecursive(arr, 0, size - 1, target);
    if (result == -1)
        printf("Element is not present in array\n");
    else
        printf("Element is present at index %d\n", result);
    return 0;
}

递归实现的逻辑与迭代版本相同,但通过函数自身调用简化了代码结构。

4. 二分查找的时间复杂度分析

二分查找的时间复杂度为 O(log n),这是因为每次查找都会将数组的查找范围缩小一半。假设数组长度为 n,那么查找的过程至多会执行 log₂(n) 次。因此,随着数据规模的增大,二分查找的效率非常高。

  • 最坏情况时间复杂度: O(log n)
  • 最优情况时间复杂度: O(1) (目标值刚好位于中间位置)
  • 平均情况时间复杂度: O(log n)

空间复杂度:

  • 迭代实现的空间复杂度为 O(1),因为只使用了常量级别的额外空间。
  • 递归实现的空间复杂度为 O(log n),因为递归调用栈会占用额外的空间。

5. 二分查找的局限性

  1. 数据必须有序:二分查找只能在有序数组上进行。如果数据无序,需要先进行排序操作,这会增加时间复杂度。
  2. 只能用于顺序存储的结构:对于链表等非顺序存储的数据结构,二分查找的效果不佳,因为无法通过索引直接访问中间元素。

6. 总结

二分查找是一种高效且常用的算法,特别适用于在大规模有序数据中查找目标值。无论是通过迭代还是递归实现,二分查找都能在 O(log n) 时间内完成查找操作,是每位程序员都应掌握的基础算法之一。

通过掌握二分查找,不仅能提升算法设计的能力,还可以在面试中应对各种查找相关的题目。

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

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

相关文章

Catf1ag CTF Crypto(六)

前言 Catf1agCTF 是一个面向所有CTF&#xff08;Capture The Flag&#xff09;爱好者的综合训练平台&#xff0c;尤其适合新手学习和提升技能 。该平台由catf1ag团队打造&#xff0c;拥有超过200个原创题目&#xff0c;题目设计注重知识点的掌握&#xff0c;旨在帮助新手掌握C…

集团数字化转型方案(十六)

为了全面推进集团的数字化转型&#xff0c;我们将实施一系列战略举措&#xff0c;包括整合最新的人工智能、大数据分析和云计算技术&#xff0c;升级企业资源规划&#xff08;ERP&#xff09;系统&#xff0c;实现业务流程的自动化与优化&#xff1b;同时&#xff0c;建立全方位…

计算机是如何工作的(2)

文章目录 一. 寄存器和存储器二. 操作系统二. 进程PCB1. pid2. 内存指针3. 文件描述符表4. 属性1) 状态2) 优先级3) 上下文4) 记账信息 一. 寄存器和存储器 存储器是内存和硬盘的通称 内存, 存储空间比硬盘小, 速度比硬盘快, 价格比硬盘高, 掉电后数据流失寄存器是CPU上的一个…

ORACLE EBS R12系统的安装及维护案例

引言&#xff1a; Oracle E-Business Suite (EBS) R12 是企业中广泛应用的一体化管理解决方案&#xff0c;涵盖了财务、人力资源、供应链等多个业务领域。以下将详细介绍如何在 Windows 系统上安装 Oracle EBS R12&#xff0c;并分享一些日常维护的技巧和最佳实践。 点击下载…

基于imx6ull平台opencv的图像采集、ffmpeg推流和Windows端拉流(多线程)

目录 一、概述二、环境要求2.1 硬件环境2.2 软件环境三、开发流程3.1 编写测试3.2 验证功能一、概述 本文档是针对imx6ull平台opencv的图像采集、ffmpeg推流和Windows端拉流。首先创建一个线程opencv通过摄像头采集视频图像,接着再创建两个线程,其中一个线程获取采集的视频图…

Python编码系列—Python中的HTTPS与加密技术:构建安全的网络通信

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

驾驭高效编程:一探C++ STL的奥秘

1.什么是STL 2.:STL的版本 2.1:原始版本 2.2:P.J版本 2.3:RW版本 2.4:SGI版本 3:STL的六大组件 4:如何学习STL 5:STL的缺陷 1.什么是STL STL(standdard template library-标准模板库):是C标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包含数据结构与算法软…

MJJ 必备自建 IDC 系统 WHMCS 开心版 圆你一个老板梦

本文首发于只抄博客,欢迎点击原文链接了解更多内容。 前言 WHMCS 是我们买 VPS 的最常见到的 IDC 系统,最近为了写 VPS 库存监控脚本,自己搭了一个 WHMCS 用来测试,顺便分享一下如何搭建属于自己的 WHMCS,圆你一个老板梦。WHMCS 开心版仅限学习、开发使用,商业用途请前往…

Linux内核学习之中断处理

Linux内核学习之中断处理 0 前言1 中断处理程序的嵌套执行1 Linux对x86异常的处理Linux中向量用途1 Linux中的中断门描述符Linux中的中断描述符硬中断软中断和tasklet软中断tasklet[^2]ksoftirqd内核线程kworker内核线程 0 前言 文本基于x86架构讲解Linux中对中断的处理&#…

Telink泰凌微如何添加Lib库

基于TLSR8258 SDK&#xff1a;b85m_ble_single_connection_sdk 1.首先把lib文件放在sdk的proj_lib文件夹中 2. properties - c/c build - Settings - TC32 C Linker - Libraries&#xff0c;把文件添加到编译设置中。注意添加的库文件名需要删除“lib前缀”。例如&#xff1…

外贸管理软件一般都有哪些功能

外贸管理软件通常被设计来帮助国际贸易企业高效管理其业务流程。这类软件的功能多样&#xff0c;这里以神卓外贸管理软件为例&#xff0c; 以下是一些常见的核心功能模块&#xff1a; 客户关系管理 (CRM) 客户信息管理询盘与报价管理销售机会跟踪 订单管理 订单生成与处理发货…

Codeforces Round 916 (Div. 3) E1. Game with Marbles(博弈论*1400)

感觉很难想。 如果你直接想的话&#xff0c;你就会发现有很多做法可以选择&#xff0c;而你根本不知道应该选哪个。 这时候可以先假设鲍勃已经取走了爱丽丝的所有的颜色的弹珠&#xff0c;&#xff08;并且以每个颜色一个弹珠的代价&#xff09;。 这时候每一项得分就是 S i …

Linux简单介绍(2)

四、软件管理机制 4.1 Linux软件管理介绍 有一个很好的软件生态圈支持&#xff0c;才是一个优秀、值得广泛使用的操作系统平台。比如PC端的window操作系统、mac操作系统&#xff0c;手机端的IOS系统&#xff0c;Android系统等。在这些操作系统上安装软件&#xff0c;方便的不能…

思特威-秋招正式批-笔试

1.在全局数据区中分配空间的变量类型有哪些 2.new和malloc的区别 3. class CData{unsigned short m_uilndex, m_uilndexFlag 9; int m_iData[10]; int m_iType;int iGetDataType() {return m_iType;} public: CData(); }CData::CData(), m_iType(5) {string strTxt "…

自修C++Primer----3.4迭代器(iterator)的介绍

目录 1.迭代器的使用 1.1迭代器运算符 1.2从一个元素指向下一个元素 1.3迭代器的类型 1.4begin和end操作符 1.5解引用操作符和成员访问 1.6引入迭代器失效 1.7全部改成大写的一个练习 2.使用迭代器运算 我们可以使用下标运算符访问string里面的字符或者是这个vector里面…

浅谈二分算法

浅谈二分算法 二分 首先知道一下二分是什么。 二分&#xff0c;是一种快速处理大型数据的方法。基本逻辑是折半查找。 设有一个共有 n n n 个数字的数组&#xff0c;要从中查询某个元素&#xff0c;就可以用二分查找。 注&#xff1a;这里的数组默认其成员数值具有单调性…

C++类和对象(总篇)

文章目录 C类和对象1、类的定义1.1类定义格式1.2访问限定符1.3类域 2、实例化2.1实例化概念 3、this指针4、类的默认成员函数5、构造函数5.1构造函数的特点5.2实例分析 6、析构函数6.1析构函数的特点6.2实例分析 7、拷贝构造函数7.1 拷贝构造函数的特点7.2实例分析7.3浅拷贝和深…

Linux中断管理

Linux 内核提供了完善的中断框架,我们只需要申请中断,然后注册中断处理函数即可,使用非常方便,不需要一系列复杂的寄存器配置。 1.Linux中断简介 中断号 每个中断都有一个中断号,通过中断号即可区分不同的中断,有的资料也把中断号叫做中断线。在 Linux 内核中使用一个 int 变…

神经网络—卷积层

1.讲解 Conv2d out_channels 参数为2时&#xff0c;会生成两个卷积核&#xff0c;分别与输入进行卷积。得到的两个输出为输出 新生成的卷积核和原来的卷积核不一定相同 in_channels (int) – Number of channels in the input image out_channels (int) – Number of channels…

Marching Cubes 算法再探

Marching Cubes 算法再探 基础过程代码mian.cppMarchingCubes.hMarchingCubes.cpp 之前做NeRF相关工作时简单看过&#xff0c;但没有深究其实现&#xff0c;知其然不知其所以然的程度&#xff0c;算是初探。 基础 为了对MC有大致了解&#xff0c;可以先根据Marching Cubes 算法…