Я искал хороший алгоритм поиска и столкнулся с поиском с интерполяцией, который имеет временную сложность O (log (log (n))) и может применяться только к равномерно распределенным массивам. Но я обнаружил, что было возможно создать алгоритм поиска, который требует тех же условий, но имеет временную сложность O (1). Вот что я придумал: (код на C ++)
int search(double Find, double* Array, const int Size) {
if (Array[0] == Array[1] && Find == Array[0]) { return 0; }
if (Array[0] == Array[1] && Find != Array[0]) { return -1; }
const double Index = (Find - Array[0]) / (Array[Size - 1] - Array[0]) * (Size - 1.0);
if (Index < 0 || Index >= Size || Array[(int)(Index + 0.5)] != Find) { return -1; }
return Index + 0.5;
}
В этой функции мы передаем число, которое мы хотим найти, указатель массива и размер массива. Эта функция возвращает индекс, где находится номер, который нужно найти, или -1, если не найден.
Объяснение: Ну, объяснить это без картинки будет сложно, я буду стараться изо всех сил ...
Поскольку массив распределен равномерно, мы можем представить все его значения на графике, с индексом (скажем, х) как абсцисса, и значением, содержащимся в массиве в этом индексе (скажем, Arr [x]) как ордината. Итак, мы можем видеть, что все точки, представленные на графике, принадлежат функции уравнения:
Array [x] = tan (A) * x + Arr [0] -> с A в качестве сформированного угла между функцией и осью X графика.
Итак, теперь мы можем преобразовать уравнение в:
x = (Arr [x] - Arr [0]) / tan ( А)
И все, х - это индекс, который нужно найти по отношению к Arr [x] (заданное значение для поиска). Мы можем просто изменить формулу на x = (Arr [x] - Array [0]) / (Array [Size - 1] - Array [0]) * (Size - 1.0), потому что мы знаем, что tan (A) = ( Массив [Размер - 1] - Массив [0]) / (Размер - 1,0).
Вопрос (Окончательно ...)
Полагаю, что эта формула уже используется в некоторых программах, его было довольно легко найти ... Итак, мой вопрос: зачем использовать поиск интерполяции вместо этого? Я что-то не понимаю?
Спасибо за терпение и помощь.