二分查找-基础

算法描述

需求

有序数组 A 中,查找值 target

  • 如果找到返回索引
  • 如果找不到返回 -1
前提

给定一个内含 n 个元素的有序数组 A,满足 Ai-1 <= Ai(1 <= i <= n-1),一个待查值 target

算法流程
  1. 设置 i = 0,j = n-1 为数组 A 的头尾索引
  2. 如果 i > j,结束查找没有找到
  3. 设置 m = floor((i + j) / 2),m 为数组 i 的中间索引,floor 是向下取整( <= (i + j) / 2的最小整数)
  4. 如果 target < Am,设置 j = m - 1,跳到第二步
  5. 如果 target > Am,设置 i = m + 1,跳到第二步
  6. 如果 target = Am结束查找找到了
代码实现
public static int binarysearch(int[] a,int target){
        int i = 0,j = a.length - 1;//设置指针和初值
        while (i <= j){//范围内还有可能的数值
            int m = (i + j) >>> 1;//(i + j) / 2中间值
            if (target < a[m]){//目标值在左边
                j = m - 1;
            }
            else if (a[m] < target){//目标值在右边
                i = m + 1;
            }
            else {//找到目标值
                return m;
            }
        }
        return -1;
    }
  1. i,j 指向的元素也要参与比较,所以循环的条件必须为 i <= j
  2. (i + j) >>> 1
    • ">>>"二进制向右移几位 无符号
    • ">>"二进制向右移几位 带符号
    • 如果使用 (i + j) / 2,当 i 和 j 过大,运算时会将 (i + j) 的结果(二进制)当作有符号数转换为十进制数,数值大时,符号位为 1,导致 (i + j) 的值为负,而 “>>>” 就避免了这种问题
  3. 全部都使用 “<” “<=”,符合数组的升序排列,使代码易读,便于修改
性能

时间复杂度

  • 最坏情况: O ( l o g   n ) O(log~n) O(log n)
  • 最好情况:如果待查元素在数组中央,只需要循环一次 O ( 1 ) O(1) O(1)
    空间复杂度
  • 需要常数个指针 i , j , m,因此额外占用的空间是 O ( 1 ) O(1) O(1)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值