基础算法学习 | 1.二分查找

95 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情

image.png

前言

基础算法学习,之前学习这些算法也都是学学忘忘,也都没有记录下来,遇到就是百度,正好趁着这个机会每天学习一下,记录下来,和大家分享一下。

坚持,坚持,坚持!!!

二分查找

二分查找的基本思想主要就是将n个元素分成大致相等的两部分,取a[n/2]与x做比较,如果x=a[n/2],则找到x,算法中止;如果x<a[n/2],则只要在数组a的左半部分继续搜索x,如果x>a[n/2],则只要在数组a的右半部搜索x,直到找到对应的数据。

算法描述

  • 1.前提:有已排序数组 a(假设已经做好)

  • 2.定义左边界 l、右边界 r,确定搜索范围,循环执行二分查找(3、4两步)

  • 3.获取中间索引 m = (l + r) / 2

  • 4.中间索引的值 a[m] 与目标值 t 进行比较

    • 1.a[m] == t 表示找到,返回中间索引

    • 2.a[m] > t,中间值右侧的其它元素都大于 t,无需比较,中间索引左边去找,m - 1 设置为右边界,重新查找

    • 3.a[m] < t,中间值左侧的其它元素都小于 t,无需比较,中间索引右边去找,m + 1 设置为左边界,重新查找

  • 5.当 l ≥ r 时,表示没有找到,应结束循环

算法实现

public static int binarySearch(int[] a, int t) {
    // 已有排序数据a
    // 1.定义左边界l和右边界r以及中间索引m
    int l = 0, r = a.length - 1, m;
    while (l <= r) {
        // 2.获取中间索引m
        m = (l + r) / 2;
        if (a[m] == t) {
            // 3.集合中间索引的值 == 目标值t,直接返回对应索引m
            return m;
        } else if (a[m] > t) {
            // 4.集合中间索引的值 > 目标值t,右边界r缩小,m-1,继续循环查找
            r = m - 1;
        } else {
            // 5.集合中间索引的值 < 目标值t,左边界l扩大,m+1,继续循环查找
            l = m + 1;
        }
    }
    // 6.直至左右边界重合查不到目标值后返回-1
    return -1;
}

测试代码

public static void main(String[] args) {
    int[] array = {1, 3, 8, 11, 20, 35, 40, 47, 48, 49, 60};
    int target = 40; // 40, 42
    int idx = binarySearch(array, target);
    System.out.println(idx);
}

结果

image.png

image.png

解决整数溢出问题

当 l 和 r 都较大时,l + r 有可能超过整数范围,造成运算错误,解决方法有两种:

int m = l + (r - l) / 2;

还有一种是:

int m = (l + r) >>> 1;

大家多多讨论学习salute 9114033af99080ba265e881d386c85fb.jpg