При написании некоторого кода сегодня я столкнулся с обстоятельством, которое заставило меня написать бинарный поиск, которого я никогда раньше не видел. Есть ли у этого бинарного поиска имя, и действительно ли это «бинарный» поиск?
Мотивация
Прежде всего, чтобы облегчить понимание поиска, я объясню пример использования, который породил его создание.
Скажем, у вас есть список заказанных номеров. Вас просят найти индекс числа в списке, который является самым близким к x.
int findIndexClosestTo(int x);
Звонки на findIndexClosestTo()
всегда следуют этому правилу:
Если последний результат findIndexClosestTo()
был i
, то индексы ближе к i
имеют большую вероятность быть результатом текущего вызова на findIndexClosestTo()
.
Другими словами, индекс, который нам нужно найти на этот раз, скорее будет ближе к последнему, который мы нашли, чем дальше от него.
Например, представьте себе симулированного мальчика, который ходит влево и вправо по экрану. Если мы часто запрашиваем указатель местонахождения мальчика, скорее всего, он где-то рядом с последним местом, где мы его нашли.
Алгоритм
Учитывая приведенный выше случай, мы знаем, что последний результат findIndexClosestTo()
был i
(если это фактически первый раз, когда вызывается функция, i
по умолчанию равен среднему индексу списка, для простоты, хотя отдельный двоичный поиск для поиска результата первого вызова на самом деле был бы быстрее), и функция была вызвана снова. Учитывая новое число x
, мы следуем этому алгоритму, чтобы найти его индекс:
interval = 1;
- Номер, который мы ищем,
x
, расположен на i
? Если это так, верните i
;
- Если нет, определите, находится ли
x
выше или ниже i
. (Помните, список отсортирован.)
- Переместить
interval
индексов в направлении x
.
- Если мы нашли
x
в нашем новом местоположении, верните это местоположение.
- Двойной
interval
. (т.е. interval *= 2
)
- Если мы прошли
x
, вернемся interval
индексы, установите interval = 1
, перейдите к 4.
Учитывая приведенное выше правило вероятности (под заголовком «Мотивация»), мне представляется, что это наиболее эффективный способ найти правильный индекс. Вы знаете более быстрый способ?