使用二分查找来定位IP对应的省份地址(一)

二分查找 BS

通过IP地址来查找IP归属地,IP地址是什么?

202.102.133.13

结果呢?


IP地址查询

此时这个查询是在一个很大的IP地址库中来实现。地址库中包括IP地址范围和归属地的对应关系


二分查找最简单的情况是什么?

  • 不存在重复元素
  • 有序数组
  • 查找 值=给定值的元素(这个是什么意思??)

典型的问题有以下几种——

典型的BS
变体1:查找第一个值等于给定值的元素

这个题目是什么意思呢?先看下图——


变体1:比如上面这样一个有序数组,其中,a[5],a[6],a[7] 的值都等于 8,是重复的数据。我们希望查找第一个等于 8 的数据,也就是下标是 5 的元素。

我们来看看变体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;
}

我们需要注意的是:
a[mid]和value的关系有三种,大于小于等于
high 和 low 的更新方式是这样的:high = mid - 1; low = mid + 1

  • 上面的情况只应对了a[mid]<或者>value的情况,如果a[mid] = value呢?
    我们需要做的就是确认这个a[mid]是不是第一个值等于给定值的元素
    如果做到这个呢?我们有两种判断方法——
  1. 如果mid等于0,那么这个元素已经是该数组的第一个元素,那它一定是我们要找的。
  2. 如果mid不等于0,但是a[mid]的前一个元素a[mid-1]不等于value,那也说明a[mid]是我们要找的第一个值等于给定值的元素。
  3. 如果我们发现a[mid]前面的一个元素a[mid-1]也等于value,那说明此时的a[mid]肯定不是第一个,那我们应该怎么做呢?更新!,也就是更新high = mid - 1, 因为我们要找的元素肯定出现在[low, mid-1]之间。

变体2:查找最后一个值等于给定值的元素

我们再来分析一下最后一个值的情况——

  1. 如果a[mid]这个元素已经是数组中最后一个元素,那它肯定是我们要找的。
  2. 如果a[mid+1]的值不等于value,呢也说明a[mid]是要找的
  3. 如果a[mid]后面的a[mid+1]也等于value, 那么我们就要更新low, 怎么更新呢?low=mid+1, 因为要找的元素肯定出现在[mid+1, high]之间。

你可能感兴趣的:(使用二分查找来定位IP对应的省份地址(一))