15 | 二分查找(上):如何用最省内存的方式实现快速查找功能?

123 阅读1分钟

无处不在的二分思想

  • 生活中猜数

  • 适用场景:有序数组查找

  • 时间复杂度 O(logn)

    • 有时甚至会比O(1)时间复杂度还高效
    • 2的32次方(42亿)也只需要比较32次

二分的递归与非递归实现

  • 基础版的二分查找

    • 有序数组
    • 不存在重复元素
  • 需要注意的点

    • 循环退出条件:low<=high

    • mid取值:mid=(low+high)/2 可能造成溢出

      • low+(high-low)/2\

      • 用移位代替除法 low+((high-low)>>1)

    • low和high更新

      • low=mid 或者 high=mid可能导致死循环\

| ``` //顺序查找

public int bsearch(int[] a, int n, int value) {   int low = 0;   int high = n - 1;    while (low <= high) {     int mid = (low + high) / 2;     if (a[mid] == value) {       return mid;     } else if (a[mid] < value) {       low = mid + 1;     } else {       high = mid - 1;     }   }    return -1; }
//递归查找

// 二分查找的递归实现 public int bsearch(int[] a, int n, int val) { return bsearchInternally(a, 0, n - 1, val); } private int bsearchInternally(int[] a, int low, int high, int value) { if (low > high) return -1; int mid = low + ((high - low) >> 1); if (a[mid] == value) { return mid; } else if (a[mid] < value) { return bsearchInternally(a, mid+1, high, value); } else { return bsearchInternally(a, low, mid-1, value); } }

| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

# 二分应用场景的局限性

-   基于数据,可以顺序查找

    -   链表不可以

-   针对有序数据

    -   先排序再二分

-   数据量太小或太大不需要二分查找

    -   数据量小 遍历即可
    -   数据量大 内存吃不消

# 总结

-   二分查找时间复杂度O(logn)

-   条件苛刻

    -   数组
    -   有序
    -   数据规模适中