基础算法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.实际上,二分查找有诸多变体,一旦使用变体的实现代码,则左右边界的选取会有变化。也就是说做题的时候要根据实际情况分析。

相关推荐
喜欢理工科6 分钟前
18 C语言标准头文件
c语言·python·算法·c语言标准头文件
a130960233611 分钟前
编译原理 pl0 词法解析器 使用状态机与状态矩阵,和查找上一步得到分析
线性代数·算法·矩阵
程序员鱼皮25 分钟前
2025 年最全Java面试题 ,热门高频200 题+答案汇总!
java·后端·面试
爱笑的Sunday29 分钟前
【LeetCode 题解】算法:15.三数之和
java·数据结构·算法·leetcode
爱编程的王小美33 分钟前
srpingboot-后端登录注册功能的实现
java·数据库·sql
该怎么办呢40 分钟前
原生android实现定位java实现
android·java·gitee
没差c1 小时前
处理json,将接口返回的数据转成list<T>,和几个时间处理方法的工具类
java·json·list
Hanson Huang1 小时前
23中设计模式-迭代器(Iterator)设计模式
java·设计模式·迭代器模式·行为型设计模式
John Art1 小时前
PAT甲级(Advanced Level) Practice 1028 List Sorting
算法
天草二十六_简村人1 小时前
Rabbitmq消息被消费时抛异常,进入Unacked 状态,进而导致消费者不断尝试消费(下)
java·spring boot·分布式·后端·rabbitmq