使用二进制搜索在排序数组中搜索密钥的前驱

时间:2017-06-08 03:37:52

标签: arrays algorithm binary-search

对于排序的int数组,BS算法返回密钥的前导。

例如,给定数组{3,5,7,9,11},BS(15)= 11,BS(9)= 7.当数组中不存在前驱时,可以定义算法的行为(例如BS(3))。我认为解决方案是二进制搜索算法的一种变体,但我无法得到正确的解。这是我到目前为止,它是不正确的:

int BinarySearch5(vector<int> &data, int left, int right, int key) {
  // if pred does not exist in the array, then return the smallest element in the array
  if (left >= right) {
    return left;
  } 
  int mid = left + (right - left) / 2;
  if (data[mid] >= key) {  // search left
    return BinarySearch5(data, left, mid - 1, key);
  } else {  // data[mid] < key, search right but including mid
    return BinarySearch5(data, mid, right, key);
  }
}

1 个答案:

答案 0 :(得分:0)

如果键值大于向量中的最大值,则代码会出现分段错误。如果为您的向量{3, 5, 7, 9, 11}提供了密钥20,则BS(0,4)会调用BS(2,4),然后调用BS(3,4),然后再调用BS(3,4)并依次调用。因此,一旦data[mid] > key我们知道mid可能的答案。但如果有一个小于data[mid]且位于mid右侧的元素,则该元素的位置应该是答案。

避免该问题的一种可能方法如下:存储mid作为答案。如果BS(mid+1,r)的值inddata[ind] > key,我们会返回ind而不是mid。否则返回mid

int BinarySearch5(vector<int> &data, int left, int right, int key) {
  if (left >= right) {
    return left;
  }

  int mid = left + (right - left) / 2;
  if (data[mid] >= key) {
    return BinarySearch5(data, left, mid - 1, key);
  } else {
    int t = BinarySearch5(data, mid+1, right, key); // See the change here
    return data[t]<key? t:mid;
  }
}