算法 二分查找的变种以及注意事项

二分查找

普通的二分查找

public static int bSearch(int[] array, int num) {
   int low = 0, high = array.length;
    int mid;
    while (low <= high) {
        mid = low + (high - low) / 2;
        if (array[mid] == num) {
            return mid;
        } else if (array[mid] > num) {
            high = mid - 1;
        } else {
            low = mid + 1;
        }
    }
    return -1;
}

变种

1.找到第一个等于key的元素

//找到第一个等于key的元素下标
public static int bSearchFirstEquals(int[] array, int key) {
     int low = 0, high = array.length-1;
     int mid;
     while (low <= high) {
         mid = low + (high - low) / 2;
         if (array[mid] >= key) {
             high = mid - 1;
         } else {
             low = mid + 1;
         }
     }
     if (low < array.length && array[low] == key) {
         return low;
     }
     return -1;
 }

2.返回最后一个等于key元素下标

 public static int bSearchLastEquals(int[] array, int key) {
    int low = 0, high = array.length - 1;
    int mid;
    while (low <= high) {
        mid = low + (high - low) / 2;
        if (array[mid] > key) {
            high = mid - 1;
        } else {//如果array[mid]==key也会在后一半元素中查找
            low = mid + 1;
        }
    }
    if (high < array.length && array[high] == key) {
        return high;
    }
    return -1;
}

3.最后一个小于等于key的元素

 public static int bSearchLastLessAndEquals(int[] array, int key) {
   int low = 0, high = array.length - 1;
    int mid;
    while (low <= high) {
        mid = low + (high - low) / 2;
        if (array[mid] > key) {
            high = mid - 1;
        } else {
            low = mid + 1;
        }
    }
    return high;
}

4.第一个大于key的元素

public static int bSearchLastMoreThan(int[] array, int key) {
    int low = 0, high = array.length - 1;
    int mid;
    while (low <= high) {
        mid = low + (high - low) / 2;
        if (array[mid] >= key) {
            high = mid - 1;
        } else {
            low = mid + 1;
        }
    }
    return low;
}

需要注意的几点:

  1. 使用递归的话要记得判断low和high是否合法 增强代码的鲁棒性
  2. 一般不建议使用递归实现 原因是存在压栈和出栈的消耗
  3. 对于中间值mid的计算 如果使用mid=(low+high)/2 存在极端情况下low+high的结果溢出,因此使用mid=low+(high-low)/2 更好
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值