【算法系列 | 8】深入解析查找算法之—二分查找

这篇具有很好参考价值的文章主要介绍了【算法系列 | 8】深入解析查找算法之—二分查找。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【算法系列 | 8】深入解析查找算法之—二分查找,算法系列,赠书活动,算法,二分查找,查找算法,Python,原力计划

序言

心若有阳光,你便会看见这个世界有那么多美好值得期待和向往。

决定开一个算法专栏,希望能帮助大家很好的了解算法。主要深入解析每个算法,从概念到示例。

我们一起努力,成为更好的自己!

今天第8讲,讲一下查找算法的二分查找

1 基础介绍

查找算法是很常见的一类问题,主要是将一组数据按照某种规则进行排序。

以下是一些常见的查找算法及其应用场景:

  1. 布隆过滤器(Bloom Filter):适用于判断一个元素是否存在于一个大规模的数据集中,时间复杂度为O(1),但有一定的误判率。
  2. 二分查找(Binary Search):适用于有序数组中查找元素,时间复杂度为O(log n);
  3. 哈希表查找(Hash Table:适用于快速查找和插入元素,时间复杂度为O(1),但需要额外的存储空间;
  4. 线性查找(Linear Search):适用于无序数组中查找元素,时间复杂度为O(n);
  5. 插值查找(Interpolation Search):适用于有序数组中查找元素,时间复杂度为O(log log n),但是对于分布不均匀的数据集效果不佳;
  6. 斐波那契查找(Fibonacci Search):适用于有序数组中查找元素,时间复杂度为O(log n),但需要额外的存储空间;
  7. 树表查找(Tree Search):适用于快速查找和插入元素,时间复杂度为O(log n),但需要额外的存储空间;
  8. B树查找(B-Tree):适用于大规模数据存储和查找,时间复杂度为O(log n),但需要额外的存储空间;

一、二分查找介绍

1.1 原理介绍

二分查找算法(Binary Search)是一种用于在有序数据集合中查找目标元素的高效搜索算法。

它的实现原理基于分而治之(Divide and Conquer)的思想,通过将查找范围逐渐缩小一半来快速定位目标元素。

下面详细讲解二分查找算法的实现原理:

前提条件

  • 数据集合必须是有序的通常是升序排列的。
  • 数据集合应为静态,不应频繁插入或删除元素。

步骤

  1. 初始化指针:首先,确定查找范围,通常是整个数据集合。然后,初始化两个指针:

    • 左指针left)指向查找范围的起始位置,通常是0。
    • 右指针right)指向查找范围的结束位置,通常是数据集合的最后一个元素的索引。
  2. 查找中间元素:计算左右指针的中间位置,即 (left + right) / 2

  3. 比较中间元素:将目标元素与中间位置的元素进行比较。

    • 如果目标元素等于中间位置的元素,则找到了目标元素,查找结束。
    • 如果目标元素小于中间位置的元素,则更新右指针为中间位置的前一个位置,将查找范围缩小为左半部分。
    • 如果目标元素大于中间位置的元素,则更新左指针为中间位置的后一个位置,将查找范围缩小为右半部分。
  4. 重复步骤2和步骤3:不断重复计算中间位置和比较中间元素,直到以下任一条件满足:

    • 找到目标元素,即目标元素等于中间位置的元素。
    • 左指针大于右指针,表示查找范围为空,目标元素不存在。

示例: 假设有一个有序数组 arr,要查找目标元素 target

arr = [1, 3, 5, 7, 9, 11, 13, 15, 17] target = 9

初始时,left 指向0,right 指向8,中间元素为 arr[4],即9。

  1. 目标元素与中间元素相等,查找结束,找到了目标元素。

二分查找算法的关键在于每一次迭代都将查找范围缩小一半,这导致算法的时间复杂度为 O(log n),其中 n 是数据集合的大小。这使得二分查找非常高效,特别适用于大规模的有序数据集合。但需要注意的是,由于它要求数据集合必须是有序的,因此如果数据无序,需要先进行排序操作。

1.2 优缺点

优点:

  1. 高效性:二分查找的时间复杂度为 O(log n),其中 n 是数组的长度。由于每次迭代都将搜索范围减半,因此算法的时间复杂度相对较低。在大型有序数组中,二分查找比线性查找要快得多。
  2. 简单易实现:二分查找的实现相对简单,只需按照一定的步骤进行比较和调整指针即可。

缺点:

  1. 仅适用于有序数组:二分查找要求数组必须是有序的,否则无法保证正确的查找结果。如果数组未排序,需要先进行排序操作,这可能会增加额外的时间复杂度。
  2. 内存占用较大:二分查找通常需要占用较大的内存空间,因为它需要存储整个数组。在某些情况下,这可能会成为一个问题,特别是当处理大型数组时。
  3. 难以处理插入和删除操作:二分查找适用于静态数组,即不经常进行插入和删除操作的数组。如果需要频繁地插入或删除元素,由于需要保持数组有序性,可能需要进行额外的操作,导致效率降低。

所以,二分查找算法在查找有序数组中的元素时非常高效。它的主要优点是高效性和简单易实现。

然而,它的缺点是仅适用于有序数组、内存占用较大以及难以处理插入和删除操作。

因此,在选择使用二分查找时,需要根据具体的问题和数据结构的特点综合考虑其优缺点。

1.3 复杂度

这种算法的效率很高,时间复杂度为O(log n),适用于大规模数据集合。

1.4 使用场景

二分查找适用于以下场景:

  1. 有序数组:二分查找要求数组是有序的,因此当我们需要在一个已排序的数组中查找某个元素时,可以使用二分查找来提高查找效率。

  2. 查找静态数据:如果数据集合是静态的,即不会频繁地插入、删除或修改元素,而是在固定的数据集上进行查找操作,那么二分查找是一个很好的选择。

  3. 大型数据集合:二分查找的时间复杂度为 O(log n),其中 n 是数组的长度。相比线性查找的 O(n) 时间复杂度,二分查找在大型数据集合中的查找效率更高。

  4. 查找边界值:由于二分查找可以快速定位有序数组中的中间元素,因此它在查找边界值或者某个特定范围内的元素时非常有用。例如,在一个有序整数数组中查找某个元素第一次出现的位置或最后一次出现的位置。

  5. 数值区间判断:对于满足某种数值规律的数组,可以使用二分查找进行区间判断。例如,对于一个有序的数值范围数组,可以使用二分查找确定某个数值是否在某个区间内。

二、代码实现

2.1 Python实现

代码示例

def binary_search(arr, target):
    left = 0
    right = len(arr) - 1

    while left <= right:
        mid = (left + right) // 2

        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            left = mid + 1
        else:
            right = mid - 1

    return -1  # 如果未找到目标元素,返回 -1

# 示例使用
arr = [1, 3, 5, 7, 9, 11, 13]
target = 7

result = binary_search(arr, target)

if result != -1:
    print("目标元素在数组中的索引为:", result)
else:
    print("目标元素不在数组中")

代码讲解

在这个示例中,我们定义了一个名为 binary_search 的函数,它接受一个有序数组 arr 和目标元素 target 作为输入参数。算法使用两个指针 left 和 right 来表示搜索的区间。开始时,left 指向数组的起始位置,right 指向数组的末尾位置。

然后,算法进入一个循环,当 left 小于等于 right 时,持续执行以下步骤:计算中间元素的索引 mid,并将其与目标元素进行比较。如果 arr[mid] 等于 target,则找到了目标元素,返回 mid。如果 arr[mid] 小于 target,则说明目标元素可能在 mid 的右侧,将 left 更新为 mid + 1

  1. 如果 arr[mid] 大于 target,则说明目标元素可能在 mid 的左侧,将 right 更新为 mid - 1
  2. 如果循环结束时仍未找到目标元素,说明目标元素不存在于数组中,返回 -1。

运行结果

运行上述代码的结果将会是:

目标元素在数组中的索引为: 3

根据给定的有序数组 [1, 3, 5, 7, 9, 11, 13] 和目标元素 7,经过二分查找算法,找到了目标元素在数组中的索引位置为 3。

2.2 Java实现

代码示例

public class BinarySearch {
    public static int binarySearch(int[] arr, int target) {
        int left = 0;
        int right = arr.length - 1;

        while (left <= right) {
            int mid = left + (right - left) / 2;

            if (arr[mid] == target) {
                return mid;
            } else if (arr[mid] < target) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }

        return -1;  // 如果未找到目标元素,返回 -1
    }

    // 示例使用
    public static void main(String[] args) {
        int[] arr = {1, 3, 5, 7, 9, 11, 13};
        int target = 7;

        int result = binarySearch(arr, target);

        if (result != -1) {
            System.out.println("目标元素在数组中的索引为: " + result);
        } else {
            System.out.println("目标元素不在数组中");
        }
    }
}

代码讲解

在这个示例中,定义了一个名为 BinarySearch 的类,其中包含了一个静态方法 binarySearch。该方法接受一个有序数组 arr 和目标元素 target 作为输入参数,并返回目标元素在数组中的索引。

在 binarySearch 方法中,使用两个指针 left 和 right 来表示搜索的区间。开始时,left 指向数组的起始位置,right 指向数组的末尾位置。

然后,算法进入一个循环,当 left 小于等于 right 时,持续执行以下步骤:

  1. 计算中间元素的索引 mid,并将其与目标元素进行比较。
  2. 如果 arr[mid] 等于 target,则找到了目标元素,返回 mid
  3. 如果 arr[mid] 小于 target,则说明目标元素可能在 mid 的右侧,将 left 更新为 mid + 1
  4. 如果 arr[mid] 大于 target,则说明目标元素可能在 mid 的左侧,将 right 更新为 mid - 1
  5. 如果循环结束时仍未找到目标元素,说明目标元素不存在于数组中,返回 -1。

运行结果

运行上述 Java 代码的结果将会是:

目标元素在数组中的索引为: 3

根据给定的有序数组 [1, 3, 5, 7, 9, 11, 13] 和目标元素 7,经过二分查找算法,找到了目标元素在数组中的索引位置为 3。

三、图书推荐

清华社【秋日阅读企划】领券立享优惠

IT好书 5折叠加10元 无门槛优惠券:活动

活动时间:9月4日-9月17日,先到先得,快快抢

【算法系列 | 8】深入解析查找算法之—二分查找,算法系列,赠书活动,算法,二分查找,查找算法,Python,原力计划

图书名称:

  • 《Python从入门到精通(第3版)(软件开发视频大讲堂)》

图书介绍

【算法系列 | 8】深入解析查找算法之—二分查找,算法系列,赠书活动,算法,二分查找,查找算法,Python,原力计划

《Python从入门到精通(第3版)》从初学者角度出发,通过通俗易懂的语言、丰富多彩的实例,详细介绍了使用Python进行程序开发应该掌握的各方面技术。

全书共分27章,包括初识Python、Python语言基础、运算符与表达式、流程控制语句、列表和元组、字典和集合、字符串、Python中使用正则表达式、函数、面向对象程序设计、模块、文件及目录操作、操作数据库、使用进程和线程、网络编程、异常处理及程序调试、Pygame游戏编程、推箱子游戏、网络爬虫开发、火车票分析助手、数据可视化、京东电商销售数据分析与预测、Web编程、Flask框架、e起去旅行网站、Python自动化办公、AI图像识别工具等内容。

书中所有知识都结合具体实例进行介绍,涉及的程序代码都给出了详细的注释,读者可轻松领会Python程序开发的精髓,快速提升开发技能。 

【算法系列 | 8】深入解析查找算法之—二分查找,算法系列,赠书活动,算法,二分查找,查找算法,Python,原力计划【算法系列 | 8】深入解析查找算法之—二分查找,算法系列,赠书活动,算法,二分查找,查找算法,Python,原力计划【算法系列 | 8】深入解析查找算法之—二分查找,算法系列,赠书活动,算法,二分查找,查找算法,Python,原力计划 

参与方式 

图书数量:本次送出 3 本   !!!⭐️⭐️⭐️
活动时间:截止到 2023-09-16 12:00:00

抽奖方式:

  • 评论区随机抽取小伙伴!

留言内容,以下方式都可以:

  • 根据文章内容进行高质量评论

参与方式:关注博主、点赞、收藏,评论区留言 

中奖名单 

🍓🍓 获奖名单🍓🍓

 中奖名单:请关注博主动态

名单公布时间:2023-09-16 下午文章来源地址https://www.toymoban.com/news/detail-728244.html

到了这里,关于【算法系列 | 8】深入解析查找算法之—二分查找的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【算法系列 | 7】深入解析查找算法之—布隆过滤器

    【算法系列 | 7】深入解析查找算法之—布隆过滤器

    心若有阳光,你便会看见这个世界有那么多美好值得期待和向往。 决定开一个算法专栏,希望能帮助大家很好的了解算法。主要深入解析每个算法,从概念到示例。 我们一起努力,成为更好的自己! 今天第3讲,讲一下排序算法的选择排序(Selection Sort) 查找算法是很常见的

    2024年02月14日
    浏览(12)
  • 【算法系列篇】二分查找——这还是你所知道的二分查找算法吗?

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

    在生活中,我们往往会遇到在数组中查找某个确定的元素的时候,通常我们会选择使用暴力解法,这样虽然简单,但是时间复杂度是O(N),时间效率比较低。那么是否有方法可以使得在具有二段性的数组中找某一特定的元素的时间复杂度低于0(N)呢?答案是肯定的,当我们可以

    2024年02月11日
    浏览(14)
  • 【Python查找算法】二分查找、线性查找、哈希查找

    【Python查找算法】二分查找、线性查找、哈希查找

    目录 1 二分查找算法  2 线性查找算法 3 哈希查找算法         二分查找(Binary Search)是一种用于在有序数据集合中查找特定元素的高效算法。它的工作原理基于将数据集合分成两半,然后逐步缩小搜索范围,直到找到目标元素或确定目标元素不存在。 以下是二分查找的

    2024年02月08日
    浏览(12)
  • Python数据结构与算法篇(五)-- 二分查找与二分答案

    Python数据结构与算法篇(五)-- 二分查找与二分答案

    1.1 定义         二分查找又称折半查找、二分搜索、折半搜索等,是一种在静态查找表中查找特定元素的算法。         所谓静态查找表,即只能对表内的元素做查找和读取操作,不允许插入或删除元素。         使用二分查找算法,必须保证查找表中存放的是有

    2023年04月20日
    浏览(9)
  • 【数据结构与算法】python实现二分查找

    【数据结构与算法】python实现二分查找

    二分查找 又称折半查找,它是一种效率较高的查找方法 原理:首先,假设表中元素是按升序排列,将表中间位置记录的与查找比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的大于查找,则

    2024年02月05日
    浏览(12)
  • 【算法】【Python3、动态规划、贪心、二分查找】力扣1671. 得到山形数组的最少删除次数

    1671. 得到山形数组的最少删除次数 给定一个整数数组 nums ,我们定义该数组为山形数组当且仅当: nums 的长度至少为 3。 存在一个下标 i 满足 0 i len(nums) - 1 且: nums[0] nums[1] ... nums[i - 1] nums[i] nums[i] nums[i + 1] ... nums[len(nums) - 1] 现在,给定整数数组 nums ,我们的目标是将其变为

    2024年01月18日
    浏览(12)
  • 【经典LeetCode算法题目专栏分类】【第6期】二分查找系列:x的平方根、有效完全平方数、搜索二位矩阵、寻找旋转排序数组最小值

    【经典LeetCode算法题目专栏分类】【第6期】二分查找系列:x的平方根、有效完全平方数、搜索二位矩阵、寻找旋转排序数组最小值

    《博主简介》 小伙伴们好,我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。 ✌ 更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍 感谢小伙伴 们点赞、关注! class   Solution :      def   mySqrt ( self ,  x :   int )   -   int :       

    2024年02月04日
    浏览(16)
  • 【算法系列 | 5】深入解析排序算法之——快速排序

    【算法系列 | 5】深入解析排序算法之——快速排序

    你只管努力,其他交给时间,时间会证明一切。 文章标记颜色说明: 黄色 :重要标题 红色 :用来标记结论 绿色 :用来标记一级论点 蓝色 :用来标记二级论点 决定开一个算法专栏,希望能帮助大家很好的了解算法。主要深入解析每个算法,从概念到示例。 我们一起努力

    2024年02月08日
    浏览(10)
  • 【算法系列 | 1】深入解析排序算法之——冒泡排序

    【算法系列 | 1】深入解析排序算法之——冒泡排序

    你只管努力,其他交给时间,时间会证明一切。 文章标记颜色说明: 黄色 :重要标题 红色 :用来标记结论 绿色 :用来标记一级论点 蓝色 :用来标记二级论点 决定开一个算法专栏,希望能帮助大家很好的了解算法。主要深入解析每个算法,从概念到示例。 我们一起努力

    2024年02月08日
    浏览(7)
  • 【算法系列 | 2】深入解析排序算法之插入排序

    【算法系列 | 2】深入解析排序算法之插入排序

    你只管努力,其他交给时间,时间会证明一切。 文章标记颜色说明: 黄色 :重要标题 红色 :用来标记结论 绿色 :用来标记一级论点 蓝色 :用来标记二级论点 决定开一个算法专栏,希望能帮助大家很好的了解算法。主要深入解析每个算法,从概念到示例。 我们一起努力

    2024年02月08日
    浏览(8)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包