算法 --- 二分查找

99 阅读1分钟

二分查找的优势?

提前查找效率

二分查找的前提条件?

  • 数据必须是有序的
  • 如果数据是乱的,先排序再用二分查找得到的索引没有实际意义,只能确定前数字在数组中是否存在,因为排序之后数字的位置就可能发生变化了

二分查找的过程

  • min和max表示当前要查找的范围;
  • mid是在min和max中间的;
  • 如果要查找的元素在mid的左边,缩小范围时min不变,max等于mid减1
  • 如果要查找的元素在mid的右边,缩小范围时max不变,min等于mid加1

简单使用例子


int[] arr = {7, 44, 66, 88, 134, 147, 358, 369};
System.out.println("查询数值在数组中的下标为" + binarySearch(369, arr));//7


public static int binarySearch(int number, int[] array) {
    System.out.println("array length:"+array.length);//8
    int min = 0;
    int max = array.length - 1;
    int mid = 0;
    while (true) {
        if (min > max) return -1;//数值不存在
        mid = (min + max) / 2;
        if (array[mid] > number) {
            max = mid - 1;
        } else if (array[mid] < number) {
            min = mid + 1;
        } else {
            return mid;
        }
    }
}

二分查找改进 -- 插值查找

mid = min + ((number-arr[min]) / (arr[max] - arr[min])) * (max - min)

二分查找改进 --斐波那契查找

min = min + 黄金分割点左半边长度 -1 

三种查询各自的特点

相同点

都是通过不断的缩小范围来查找对应的数据的

不同点

计算mid的方式不一样

  • 二分查找: mid每次都是指向范围的中间位置
  • 插值查找: mid尽可能的靠近要查找的数据,但是要求数据尽可能的分布均匀
  • 斐波那契额查找: 根据黄金分割点来计算mid指向的位置