漫谈算法——二分查找的应用

159 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第17天,点击查看活动详情

前言

我们学习完二分查找后,接下来我们就是来看一下它的应用,虽然原理很简单明了的,但是到应用到现实场景后又是云里雾里的。所以我们要自己多多练习的。

二分查找的应用

我们工作生活中使用的计算机都是有IP地址的,那么如果通过IP地址快速的寻找到对应的归属地呢?因为IP地址有非常的多的,在数据量巨大的情况下如何定位到IP地址呢。首先IP区间和归属地是有对应的映射关系的。所以我们可以预处理IP地址的,将IP地址转换为整数进行从大到小进行排序。然后我们查询某个IP地址的时候,就可以根据这个IP地址找到最后一个起始地址小于等于这个IP地址的区间,检查该IP是否在这个IP区间内,如果存在的话,我们就可以返回对应的归属地址的。其实这种方式的话,就是二分查找的变形形式之一。假设我们有一个数据集,从小到大排序好的,我们使用二分查找去寻找一个对应的元素的值,使用之前的函数可以轻松的办到,但是假如我们的数据集含有重复的数据,并且我需要查找第一个该元素的对应的值,如果这时候再使用之前的方法,虽然可以查找到与给出的值相同的数据,但是它可能不是第一个元素的。这时候我们需要对代码进行修改才可以的。

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;
}

前面的部分大于和小于的部分跟常规的二分查找没有差别的,最主要的部分在于加入查找到给定值的元素后,我们要进行比较,元素值已经位于数组头了,或者该元素与前一个元素不相等时,我们就找到了第一个元素。假如并不是第一个,那么这时候我们在该元素所在的索引位置缩进一位,继续查找。依此类推。直到找到为止。

总结

二分查找的变形问题需要判断好临界条件的。不然很容易出错的。