二分查找:如何快速定位出一个 IP 地址的归属地?

133 阅读2分钟

二分查找:如何快速定位出一个 IP 地址的归属地?

如果 IP 区间与归属地的对应关系不经常更新,我们可以先预处理这些数据,让其按照起始 IP 从小到大排序。

如何来排序呢?

我们知道,IP 地址可以转化为 32 位的整型数。

所以,

我们可以将起始地址,按照对应的整型值的大小关系,从小到大进行排序。

然后,这个问题就可以转化为在有序数组中,查找最后一个小于等于某个给定值的元素”了。

当我们要查询某个 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) {
       if ((mid == 0) || (a[mid - 1] < value)) return mid;
       else high = mid - 1;
     } else {
       low = mid + 1;
     }
   }
   return -1;
 }

在有序数组中,查找第一个大于等于给定值的元素。比如,数组中存储的这样一个序列:3,4,6,7,10。如果查找第一个大于等于 5 的元素,那就是 6。


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

二分查找的变形问题,查找最后一个小于等于给定值的元素。比如,数组中存储了这样一组数据:3,5,6,8,9,10。最后一个小于等于 7 的元素就是 6。