基础算法01——二分查找(Binary Search)

二分查找(Binary Search)

  1. 二分查找算法:也称为折半查找 ,是一种在有序数组中查找特定元素的高效算法。
  2. 算法逻辑:
    • 每次取中间位置的值与待查关键字比较:
      • 如果待查关键字 比中间位置的值 ,则在有序数组的前半部分循环这个查找的过程
      • 如果待查关键字 比中间位置的值 ,则在有序数组的后半部分循环这个查找的过程
      • 每比较一次之后就更新中间位置的值,然后和带查找关键字比较
    • 一直重复上面的逻辑,(直到找到了待查找关键字)或者是(直到low的值比high的值大(数组遍历完成了都没有找到元素就结束循环了))才会结束循环

java代码演示

java 复制代码
public class ErFenChaZhao {
    public static void main(String[] args) {
        int[] array={2,4,6,7,9,102};
        int i = binarySearch(array, 102);
        if (i == -1){
            System.out.println("数组内无此元素!!!");
        }else {
            System.out.println("目标元素的位置是在数组下标为:"+ i + "的位置");
        }

    }

    /**
     * 二分查找
     * @param array:有序数组
     * @param a:目标元素
     * @return
     */
    public static int binarySearch(int[] array, int a){
       int low = 0; // 一开始最左边元素的位置
       int high = array.length-1; // 一开始最右边元素的位置
       int mid; // 中间元素
       while (low <= high){
           // 如果数组的元素是偶数的话,取的元素位置是中间两个元素的左边的元素,也就是小的那个元素(常用)
           // 如果要想取中间两个元素的右边的元素,中间元素取值表达式为 mid = (low+high+1)/2;
           mid = (low+high)/2;  // 中间元素的位置
           if (a == array[mid]){  // 把目标元素和中间元素作比较
               return mid;  // 返回中间元素的位置
           }else if (a > array[mid]){ // 如果目标元素比中间元素大,那么目标元素肯定在数组的右侧
               low = mid + 1;  // 把左边元素移动到中间元素的后一位
           }else {   // 如果目标元素比中间元素小,那么目标元素肯定在数组的左侧
               high = mid - 1; // 把右边元素移动到中间元素的后一位
           }
       }
        return -1;  // 找不到目标元素则返回-1
    };
}

注意事项:在获取中间索引值的时候(mid = (low+high)/2),可能整数溢出问题

问题分析:当low和high的值都特别大的时候,low+high就可能超过整数存储的最大值。

  • 解决办法:(替换计算(mid = (low+high)/2))
    • 修改计算式子:mid = (low+high)/2 = low + (high - low)/2
    • 使用无符号运算(这里是无符号右移一位):(low + high) >>> 1

二分查找可能的考法:

  1. 笔试题:手写二分查找算法。
  2. 选择或填空题 ,类似:
    • 有一个有序表为 1,5,8,11,19,22,31,35,40,45,48,49,50 当二分查找值为 48 的结点时,查找成功需要比较的次数
    • 使用二分法在序列 1,4,6,7,15,33,39,50,64,78,75,81,89,96 中查找元素 81 时,需要经过( )次比较
    • 在拥有128个元素的数组中二分查找一个数,需要比较的次数最多不超过多少次?

注意:

1.本文锁介绍的二分查找是以jdk中Arrays.binary Search的实现为例的。

2.实际上,二分查找有诸多变体,一旦使用变体的实现代码,则左右边界的选取会有变化。也就是说做题的时候要根据实际情况分析。

相关推荐
朝新_1 小时前
【多线程初阶】阻塞队列 & 生产者消费者模型
java·开发语言·javaee
立莹Sir1 小时前
Calendar类日期设置进位问题
java·开发语言
木子.李3472 小时前
排序算法总结(C++)
c++·算法·排序算法
季鸢3 小时前
Java设计模式之状态模式详解
java·设计模式·状态模式
闪电麦坤953 小时前
数据结构:递归的种类(Types of Recursion)
数据结构·算法
@yanyu6663 小时前
springboot实现查询学生
java·spring boot·后端
ascarl20104 小时前
准确--k8s cgroup问题排查
java·开发语言
magic 2454 小时前
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
java
爱敲代码的憨仔4 小时前
分布式协同自动化办公系统-工作流引擎-流程设计
java·flowable·oa
Gyoku Mint4 小时前
机器学习×第二卷:概念下篇——她不再只是模仿,而是开始决定怎么靠近你
人工智能·python·算法·机器学习·pandas·ai编程·matplotlib