Участник:Shovkoplyas Grigory
Идея
Рассмотрим задачу: найти слово в словаре. Если оно начинается на букву "А", то никто не будет искать его в середине, а откроет словарь ближе к началу. В чём разница между алгоритмом человека и другими? Отличие заключается в том, что алгоритмы вроде двоичного поиска не делают различий между "немного больше" и "существенно больше".
Алгоритм
Пусть двоичному поиску, но вместо деления области поиска на две примерно равные части, интерполирующий поиск производит оценку новой области поиска по расстоянию между ключом и текущим значением элемента. Если известно, что лежит между и , то следующая проверка выполняется примерно на расстоянии от .
— отсортированный массив чисел из чисел, — значение, которое нужно найти. Поиск происходит подобноПсевдокод
function interpolation_search(x) left = 0 // левая граница поиска (будем считать, что элементы массива нумеруются с нуля) right = n - 1 // правая граница поиска while a[left]x and x a[right] mid = left + (x - a[left]) / (a[right] - a[left]) * (right - left) // индекс элемента, с которым будем проводить сравнение if a[mid] == x return mid if a[mid] < x left = mid + 1 else right = mid - 1 if a[left] == x return left else return -1 // если такого элемента в массиве нет
Время работы
Асимптотически интерполяционный поиск превосходит по своим характеристикам бинарный. Если ключи распределены случайным образом, то за один шаг алгоритм уменьшает количество проверяемых элементов с
до . То есть, после -ого шага количество проверяемых элементов уменьшается до . Значит, остаётся проверить только 2 элемента (и закончить на этом поиск), когда . Из этого вытекает, что количество шагов, а значит, и время работы составляет .При "плохих" исходных данных (например, при экспоненциальном возрастании элементов) время работы может ухудшиться до
.Эксперименты показали, что интерполяционный поиск не настолько снижает количество выполняемых сравнений, чтобы компенсировать требуемое для дополнительных вычислений время (пока таблица не очень велика). Кроме того, типичные таблицы недостаточно случайны, да и разница между значениями
и становится значительной только при очень больших . На практике при поиске в больших файлах оказывается выгодным на ранних стадиях применять интерполяционный поиск, а затем, когда диапазон существенно уменьшится, переходить к двоичному.Литература
Д.Э. Кнут: Искусство программирования (том 3)
Wikipedia: Interpolation search
Wikipedia: Интерполирующий поиск