Одним из подходов является сохранение инварианта на протяжении всего двоичного поиска.В вашем конкретном случае инвариант будет:
array[low] < key
key <= array[high]
Тогда вы можете минимизировать разрыв между низким и высокимиспользуя бинарный поиск.Когда low + 1 == high
, high
будет ответом.Пример кода на C ++:
// check invariant on initial values.
if (array[low] >= key) return low;
if (array[high] < key) return high+1;
// low + 1 < high ensures high is at least low + 2, thus
// mid will always be different from low or high. It will
// stop when low + 1 == high.
while (low + 1 < high) {
int mid = low + (high - low) / 2;
if (array[mid] < key) {
low = mid; // invariant: array[low] < key
} else {
high = mid; // invariant: array[high] >= key
}
}
return high;
Ключевое различие между этим и вашим примером кода заключается в обновлении low
и high
до mid
вместо mid+1
или mid-1
, потому что мы имеемпроверив значение array[mid]
, мы можем гарантировать, что инвариант все еще сохраняется при обновлении границ.Вам также нужно проверить инвариант начальных значений, прежде чем начинать поиск.