首页 > 编程语言 >清晰易懂二分查找算法 你确定不看吗?

清晰易懂二分查找算法 你确定不看吗?

时间:2024-08-08 15:56:03浏览次数:6  
标签:二分 元素 算法 查找 数组 目标值 易懂

@

目录


前言

请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i


提示:以下是本篇文章正文内容,下面案例可供参考

简介

二分查找 (Binary Search) 是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到元素。

二分查找算法的效率很高,时间复杂度为O(log n),其中n是数组中的元素数量。这是因为每次比较后,搜索范围都会减半。

一、二分查找算法的原理是什么?

二分查找算法(Binary Search Algorithm)的原理基于分治法的思想,用于在有序数组中快速查找某一特定元素的位置。其核心原理可以概括为以下几个步骤:

1. 确定搜索范围:

首先,确定搜索的起始位置 low 和结束位置 high,这两个位置分别指向数组的第一个元素和最后一个元素。这样,就确定了整个搜索范围。

2. 计算中间位置:

在每次迭代中,计算搜索范围的中间位置 mid ,这通常是通过将 lowhigh 相加后除以2来实现的(注意防止整数溢出,更安全的写法是 mid = low+ ( high - low ) / 2 )。

3. 比较中间元素:

将中间位置上的元素与要查找的目标值 target 进行比较。

4. 调整搜索范围:

  • 如果中间元素正好是要查找的目标值,则查找成功,返回中间位置的索引。
  • 如果中间元素大于目标值,则说明目标值位于当前搜索范围的左半部分,因此将high更新为 mid - 1,以缩小搜索范围到左半部分。
  • 如果中间元素小于目标值,则说明目标值位于当前搜索范围的右半部分,因此将low更新为 mid + 1,以缩小搜索范围到右半部分。

5. 重复迭代:

重复步骤2至步骤4,直到找到目标值或搜索范围为空(即 low> high )。如果搜索范围为空,则说明数组中不存在目标值,此时可以返回-1或其他表示未找到的值。

二分查找算法之所以高效,是因为它每次迭代都将搜索范围减半,从而显著减少了需要比较的元素数量。在最坏的情况下(即目标值不存在于数组中),二分查找算法的时间复杂度为O(log n),其中n是数组中的元素数量。这使得二分查找成为处理大数据集时非常有用的工具。

需要注意的是,二分查找算法要求数组必须是有序的。如果数组无序,则需要先对其进行排序,但这可能会增加总体的时间复杂度。因此,二分查找通常用于已经排序的数组或可以在查找之前进行排序的场景中。

二、二分查找算法的优缺点是什么?

二分查找算法(Binary Search Algorithm)作为一种在有序数组中查找特定元素的算法,具有其独特的优缺点。以下是二分查找算法的主要优缺点:

优点:

  1. 效率高:
    二分查找算法的时间复杂度为O(logn),其中n是数组中的元素数量。这意味着,随着数组大小的增加,查找所需的时间增长非常缓慢,相对于线性查找(时间复杂度为O(n))来说,效率显著提高
  2. 适用范围广:
    只要数据已经排序,就可以使用二分查找算法。这在处理大量数据且需要频繁查找的场景中特别有用,如数据库索引、文件系统中的查找等。
  3. 稳定性好:
    二分查找算法的性能不会受到数组初始排列顺序(只要是有序的)的影响,每次查找的时间复杂度都是O(log n)。

缺点:

  1. 要求数据有序:
    二分查找算法要求数据必须是有序的。如果数据未排序,则需要先进行排序操作,这可能会增加额外的计算开销。在某些情况下,如果排序成本很高,使用二分查找可能并不划算。

  2. 只适用于静态数据集或可快速更新的数据集:
    二分查找算法在查找过程中不修改原数组,因此它特别适用于静态数据集或可以快速更新的数据集。如果数据集频繁变化(如频繁插入或删除元素),则每次变化后都可能需要重新排序或调整索引,这可能会降低二分查找的效率。

  3. 需要额外空间(在某些情况下):
    虽然二分查找算法本身不需要额外的存储空间来保存中间结果(因为它直接在原数组上进行查找),但在某些应用场景下(如需要记录查找路径或进行多次查找时),可能需要额外的数据结构来辅助查找过程。

  4. 对内存敏感:
    由于二分查找依赖于数组的随机访问特性,因此在内存访问速度较慢的环境中(如使用磁盘作为存储介质时),二分查找的效率可能会受到影响。

综上所述,二分查找算法是一种非常高效的查找算法,但它要求数据必须是有序的,并且可能不适用于频繁变化的数据集。在实际应用中,需要根据具体场景和需求来选择是否使用二分查找算法。

三、java 实现二分查找案例

在Java中实现二分查找算法是一个常见的编程任务。以下是一个简单的二分查找算法实现案例,该算法用于在一个有序数组中查找一个特定的元素,并返回其索引。如果未找到该元素,则返回-1。

二叉树

public class BinarySearch {  
  
    /**  
     * 二分查找算法  
     *  
     * @param arr    有序数组  
     * @param target 要查找的目标值  
     * @return 目标值在数组中的索引,如果未找到则返回-1  
     */  
    public static int binarySearch(int[] arr, int target) {  
        int low = 0; // 定义最低点  
        int high = arr.length - 1; // 定义最高点  
  
        while (low <= high) {  
            int mid = low + (high - low) / 2; // 防止溢出,计算中间位置  
            if (arr[mid] == target) {  
                // 找到目标值,返回索引  
                return mid;  
            } else if (arr[mid] < target) {  
                // 目标值在中间位置的右侧,调整最低点  
                low = mid + 1;  
            } else {  
                // 目标值在中间位置的左侧,调整最高点  
                high = mid - 1;  
            }  
        }  
  
        // 未找到目标值,返回-1  
        return -1;  
    }  
  
    public static void main(String[] args) {  
        int[] arr = {-1, 0, 3, 5, 9, 12}; // 示例数组  
        int target = 9; // 要查找的目标值  
  
        int result = binarySearch(arr, target);  
  
        if (result != -1) {  
            System.out.println("元素 " + target + " 在数组中的索引为: " + result);  
        } else {  
            System.out.println("数组中未找到元素 " + target);  
        }  
    }  
}

在这个例子中,binarySearch 方法实现了二分查找算法。它接受一个有序数组 arr 和一个目标值 target 作为参数,并返回目标值在数组中的索引。如果未找到目标值,则返回-1。

在 main 方法中,我们创建了一个示例数组 arr 和一个要查找的目标值 target,然后调用 binarySearch 方法并打印结果。

总结

二分查找算法要求数组是有序的。如果数组未排序,则需要先对其进行排序,然后再使用二分查找算法。此外,二分查找算法的时间复杂度为O(log n),其中n是数组中的元素数量,这使得它在处理大数据集时非常高效。**


我是南国以南i记录点滴每天成长一点点,学习是永无止境的!转载请附原文链接!!!

标签:二分,元素,算法,查找,数组,目标值,易懂
From: https://www.cnblogs.com/bgyb/p/18349086

相关文章

  • 学习笔记 整体二分
    整体二分是一种离线算法记[l,r]为答案的值域,[L,R]为答案的定义域。(也就是说求答案时仅考虑下标在区间[L,R]内的操作和询问,这其中询问的答案在[l,r]内)我们首先把所有操作按时间顺序存入数组中,然后开始分治。在每一层分治中,利用数据结构(常见的是树状数组)统计当前查询的......
  • python装饰器提高代码复用,减少代码量,简洁易懂
    装饰器提高代码复用,减少代码量对于一个程序程序,无论是c、java、go还是python,组成这段程序的代码需要越简单越好,要知道程序的代码越简单,代码量越少,出错的概率就小,维护起来也简单。针对python语言,装饰器是我最近发现的针对简化代码,特别有帮助的工具。下面我用两段代码,演示一下同样......
  • 冒泡 选择 二分
    importjava.util.Arrays;importjava.util.Random;importjava.util.Scanner;publicclassApp{publicstaticfinalintLENGTH=6;publicstaticRandomrandom=newRandom();publicstaticScannerscanner=newScanner(System.in);publi......
  • 整体二分
    学了一下,感觉不深刻。说是整体二分,不如说是离线的归并排序。考虑这个问题:LuoguP3834【模板】可持久化线段树2\(m\)次询问,每次询问给出\((l,r,k)\),问\([l,r]\)中第\(k\)小的值。我们首先先简化一下:如果\(m=1\),怎么维护?先二分出一个\(x\),建立树状数组维护\(\lex\)......
  • 二分法题目合集
    1.锯齿形数组找target有一个数组,前半部分有序,后半部分也有序,前半部分的开头元素大于后半部分的结尾元素,请从这个数组中找出target。解题思路:一开始我们就可以根据target和数组结尾元素的大小关系确定target属于哪个部分,之后将target和mid比较时就能根据位于哪一部分去更新l,r。......
  • 整体二分
    整体二分一类题目可以二分解决,但是有多次询问,于是考虑整体二分,主要思想为把多个查询一起解决,是一个离线算法。使用条件:答案可以二分求得。允许离线。修改对判定答案的贡献互相独立,修改之间互相独立。修改如果对判定答案有贡献,则贡献为一与判定标准无关的定值。实现首先......
  • CF1993D-二分+dp处理中位数
    CF1993D-二分+dp处理中位数大致题意给定两个正整数n和k以及另一个由n个整数组成的数组a。在一次操作中,可以选择a的任意一个大小为k的子数组,然后将其从数组中删除,而不改变其他元素的顺序。更正式地说,假设$(l,r)$是对子数组\(a_l,a_{l+1},…,a_r\)的操作,使得\(r......
  • PTA 6-13 折半查找
    6-13折半查找(15分)给一个严格递增数列,函数intSearch_Bin(SSTableT,KeyTypek)用来二分地查找k在数列中的位置。函数接口定义:int Search_Bin(SSTableT,KeyTypek)其中T是有序表,k是查找的值。裁判测试程序样例:#include<iostream>usingnamespacestd;#define......
  • 一张图带你学习Linux文件权限,简单易懂!
    你好,这里是网络技术联盟站,我是瑞哥。在Linux系统中,文件权限是确保系统安全性和完整性的重要机制。理解并正确设置文件权限,能够有效防止未授权的访问和修改,从而保护系统中的数据。文件权限文件权限是Linux系统中控制用户和组对文件和目录的访问权限的机制。每个文件和目......
  • 查找分层股东关系:在 python 中重构嵌套 if
    我想找到公司之间的股东关系。在下面的示例中,“人员1”直接拥有“公司1”50%的股份,那么需要检查“公司1”是否也拥有其他公司的股份。“公司1”拥有“公司2”50%的股份,“公司3”拥有20%的股份。这意味着“人员1”间接拥有“公司2”和“公司3”的部分股份。此......