美文网首页极客时间:数据结构与算法之美笔记
二分查找(下):如何快速定位 IP 对应的省份地址?

二分查找(下):如何快速定位 IP 对应的省份地址?

作者: 红酥手黄藤酒丶 | 来源:发表于2019-01-14 23:19 被阅读0次

    二分查找(下):如何快速定位 IP 对应的省份地址?

    通过 IP 地址查找 IP 归属地的功能,是通过维护一个很大的 IP 地址库来实现的。地址库中包括 IP 地址范围和归属地的对应关系。

    ```

    [202.102.133.0, 202.102.133.255]  山东东营市 

    [202.102.135.0, 202.102.136.255]  山东烟台 

    [202.102.156.34, 202.102.157.255] 山东青岛 

    [202.102.48.0, 202.102.48.255] 江苏宿迁 

    [202.102.49.15, 202.102.51.251] 江苏泰州 

    [202.102.56.0, 202.102.56.255] 江苏连云港

    ```   

    但是在庞大的地址库中逐一比对 IP 地址所在的区间,是非常耗时的。**假设我们有 12 完条这样的 IP 区间与归属地的对应关系,如何快速定位出一个 IP 地址的归属地呢?**

    极客时间原文链接

    二分查找的变形问题

    上一节的二分查找的代码只是最简单的一种情况,在不存在重复元素的数组中,查找 值等于给定值 的元素。最简单的二分查找写起来确实不难,但是,二分查找的变形问题就没那么好写了。

    这里有四种常见的二分查找的变形问题。

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

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

    * 查找第一个 `大于等于给定值` 的元素

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

    * 此节的内容,都是以数据从小到大排列为前提!(从小到大和从大到小思路是一样的)

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

    自己做了一下,要考虑的东西有点多,越写越乱。

    假定有下面一个有序数组,其中,a[5],a[6],a[7] 的值都等于 8,是重复的数据,我们希望查找第一个等于 8 的数据,也就是下标是 5 的元素。

    如果按上一篇中的最简单的二分查找来查询,返回值是 a[7]。

    但是 a[7] 并不是第一个等于 8 的元素,a[5] 才是。

    所以需要对上一篇中的二分查找代码做一些改动。

    ```java

    //这是一个非常简洁的写法,但是可读性比较差,难于理解

    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 {

          //为什么下面的找到值的时候会 return low?

          //因为这里的low = mid +1 实际上就又让low的值等于上一轮的 mid

          low = mid + 1;

        }

      }

      if (low < n && a[low]==value) return low;

      else return -1;

    }

    ```   

    **换一种易于理解的实现方式**

    ```java

    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;

    }

    ```

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

    ```java

    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;

    }

    ```   

    与第一种写法思路一致。

    相关文章

      网友评论

        本文标题:二分查找(下):如何快速定位 IP 对应的省份地址?

        本文链接:https://www.haomeiwen.com/subject/iiisdqtx.html