算法 - 二分查找

算法 - 二分查找

今天继续八股文学习,看一下比较常规的几个算法

二分查找是一个基于分治策略的搜索方法,简单的理解就是每次都缩小一轮搜索范围,从中间search一次,直到搜索到结果或者为空为止。

基本思路(设一个有序的数组为nums,需要查询的值是target)

  1. 设置 i = 0,j = n -1。i就是数组开头的第一个索引值,j就是最后一个索引值。
  2. 如果i > j 了,证明查询结束了没有找到结果。
  3. 然后设置一个值为m,这个m就是减少的搜索范围(应该说成是每次拿数组中间的那个值,数组的中间索引),m = (i + j )/ 2 ,有的时候会有小数,所以这个时候需要取整。
  4. 如果target的值小于数组中间的值(也就是索引值是m的值),那就意味着这个值在中间值的左边(数组中间的靠左的位置),所以 j = m - 1,数组的最大值挪到了中间值靠左的位置,然后我们再重复回到第二步继续跑。
  5. 如果target的值大于数组中间的值,意味着这个值在中间值的右边,所以 i = m + 1,数组的最小值挪到了中间值靠右的位置,然后再重复回到第二步继续跑。
  6. 当索引值m = target的时候,就直接return返回查询的结果值。
/**
 * 二分查找
 * <p>
 * 基于分治策略的的高效搜索方法。
 * <p>
 * 每轮都缩小一般的搜索范围,直到搜索到结果或者区间的结果为空的时候停止。
 */
public class BinarySearch {

    // 只能用于有序的数组的排序
    public static void main(String[] args) {
        int[] nums   = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int   target = 11;
        System.out.println(binarySearch(nums, target));
    }

    /**
     * nums
     */
    public static int binarySearch(int[] nums, int target) {
        // 第一位的索引值
        var i = 0;
        // 最后一位的索引值
        var j = nums.length - 1;
        while (i <= j) {
            // 先拿一个中间点,并且需要取整,因为有时候可能回出现小数点
            int m = i + (j - i) / 2;
            // 如果中间值的小于目标值,则往中间值的左边靠
            if (nums[m] < target) {
                i = m + 1;
            } else if (nums[m] > target) { // 如果中间值大于目标值,则往中间值的右边靠
                j = m - 1;
            } else {
                return m;
            }
        }
        // 如果找不到元素返回 -1
        return -1;
    }
}

优点

在时间和空间方面都有较好的性能。

二分查找的时间效率高,不需要额外的空间。

局限性

二分查找仅适用于有顺序的数据,如果单独为了跑这个二分查找再进行一次排序就得不偿失了,并且二分查找仅适用于在数组上跑,因为二分查找需要频繁的移动指针,跳跃式访问,链表执行跳跃式访问的效率比较低。当数据量小的时候使用线性查找比二分查找的效率要高。(下一篇写一下线性查找)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mtc8n24

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值