二分查找

学习极客时间的数据结构与算法之美的专栏,记录笔记。

1  二分查找应用场景的局限性

(1)二分查找依赖的是顺序表结构,简单点说就是数组

(2) 二分查找针对的是有序数据

(3) 数据量太大或太小不适合

    数据量太小,没必要用二分查找,比如我们在一个大小为 10 的数组中查找一个元素,不管用二分查找还是顺序遍历,查找速度都差不多。

    数据量太大,也不适合,二分查找的底层需要依赖数组这种数据结构,而数组为了支持随机访问的特性,要求内存空间连续,对内存的要求比较苛刻。比如,我们有 1GB 大小的数据,如果希望用数组来存储,那就需要 1GB 的连续内存空间。但是如果这剩余的 内存空间都是零散的,没有连续的 1GB 大小的内存空间,那照样无法申请一个 1GB 大小的数组。

2 代码模板

public int bsearch(int[] a, int n, int value) {

  int low = 0;

  int high = n - 1;

  while (low <= high) {

    int mid =low+(high-low)/2;    ((high+low)/2 如果hight和low比较大,有溢出的可能)

​    //  追求性能  mid = low + ((high - low) >> 1);

    if (a[mid] == value) {

      return mid;

    } else if (a[mid] < value) {

      low = mid + 1;

    } else {

      high = mid - 1;

    }

  }

  return -1;

}

3 二分查找的变体

3.1 查找第一个值等于给定值的元素

public int bsearch(int[] a, int n, int value) {

  int low = 0;

  int high = n - 1;

  while (low <= high) {

    int mid =  low + ((high - low) >> 1);

    if (a[mid] > value) {

      high = mid - 1;

    } else if (a[mid] < value) {

      low = mid + 1;

    } else {

      if ((mid == 0) || (a[mid - 1] != value)) return mid;

      else high = mid - 1;

    }

  }

  return -1;

}

3.2 查找最后一个值等于给定值的元素

​public int bsearch(int[] a, int n, int value) {

  int low = 0;

  int high = n - 1;

  while (low <= high) {

    int mid =  low + ((high - low) >> 1);

    if (a[mid] > value) {

      high = mid - 1;

    } else if (a[mid] < value) {

      low = mid + 1;

    } else {

      if ((mid == n - 1) || (a[mid + 1] != value)) return mid;

      else low = mid + 1;

    }

  }

  return -1;

}

​3.3 查找第一个大于等于给定值的元素

public int bsearch(int[] a, int n, int value) {

  int low = 0;

  int high = n - 1;

  while (low <= high) {

    int mid =  low + ((high - low) >> 1);

    if (a[mid] >= value) {

      if ((mid == 0) || (a[mid - 1] < value)) return mid;

      else high = mid - 1;

    } else {

      low = mid + 1;

    }

  }

  return -1;

}

3.4 查找最后一个小于等于给定值的元素

public int bsearch7(int[] a, int n, int value) {

  int low = 0;

  int high = n - 1;

  while (low <= high) {

    int mid =  low + ((high - low) >> 1);

    if (a[mid] > value) {

      high = mid - 1;

    } else {

      if ((mid == n - 1) || (a[mid + 1] > value)) return mid;

      else low = mid + 1;

    }

  }

  return -1;

}

你可能感兴趣的:(二分查找)