Интерполяционный поиск — различия между версиями
(→Реализация) |
|||
Строка 3: | Строка 3: | ||
=== Алгоритм === | === Алгоритм === | ||
− | [[Файл:Search.jpg|thumb|300px|Нахождение | + | [[Файл:Search.jpg|thumb|300px|Нахождение разделительного элемента]] |
Пусть <tex> a </tex> - отсортированный массив чисел из <tex> n </tex> чисел, <tex> x </tex> - значение, которое нужно найти. | Пусть <tex> a </tex> - отсортированный массив чисел из <tex> n </tex> чисел, <tex> x </tex> - значение, которое нужно найти. | ||
Если известно, что <tex> x </tex> лежит между <tex> a_l </tex> и <tex> a_r </tex>, то следующая проверка выполняется примерно на расстоянии <tex dpi = "180"> \frac{x - a_l}{a_r - a_l} </tex> от <tex> l </tex>. | Если известно, что <tex> x </tex> лежит между <tex> a_l </tex> и <tex> a_r </tex>, то следующая проверка выполняется примерно на расстоянии <tex dpi = "180"> \frac{x - a_l}{a_r - a_l} </tex> от <tex> l </tex>. |
Версия 22:07, 15 июня 2011
Содержание
Идея
Рассмотрим задачу: найти слово в словаре. Если оно начинается на букву "А", то никто не будет искать его в середине, а откроет словарь ближе к началу. В чем разница между алгоритмом человека и другими? Отличие заключается в том, что алгоритмы вроде двоичного не делают различий между "немного больше" и "существенно больше".
Алгоритм
Пусть
- отсортированный массив чисел из чисел, - значение, которое нужно найти. Если известно, что лежит между и , то следующая проверка выполняется примерно на расстоянии от .Время работы
При условии, что значения элементов близки к арифметической прогрессии, за один шаг алгоритм уменьшает количество проверяемых элементов с
Поэтому среднее время работы алгоритма: .
При "плохих" исходных данных (например, при экспоненциальном возрастании элементов) время работы может ухудшиться до .
Реализация
Приведем код функции
на языке C++.
int interpolation_search(double* a, int n, double x)
{
int l = 0;
int r = n - 1;
int m;
while (a[l] <= x && x <= a[r])
{
m = l + (x - a[l]) / (a[r] - a[l]) * (r - l);
if (a[m] == x)
return m;
if (a[m] < x)
l = m + 1;
else
r = m - 1;
}
if (a[l] == x)
return l;
else
return -1; // not found
}
Полезные ссылки
Д.Э. Кнут: Искусство программирования (том 3)
Wikipedia: Interpolation search