
30. Алгоритмы поиска. Использование деревьев в задачах поиска: бинарные, сбалансированные, красно-черные деревья поиска.
Асимптотические оценки времени поиска
Алгоритм + Структура данных |
Удачный поиск в среднем |
Неудачный поиск в среднем |
Вставка в среднем |
Удачный поиск в худшем случае |
Вставка в худшем случае |
Последовательный поиск в неупорядоченном массиве |
N/2 |
N |
1 |
N |
1 |
Последовательный поиск в упорядоченном массиве |
N/2 |
N/2 |
N/2 |
N |
N |
Бинарный поиск в упорядоченном массиве |
log N |
log N |
N/2 |
log N |
N |
Поиск в бинарном дереве поиска |
log N |
log N |
log N |
N |
N |
Поиск в сбалансированном дереве |
log N |
log N |
log N |
log N |
log N |
Задача поиска: пусть имеется таблица записей R1, R2,…RN, где каждой записи соответствуют ключи K1, K2,…KN. Требуется найти запись с данным ключом K. У задачи может быть два исхода: удачный, когда найдено положение нужного ключа, и неудачный, когда установлено, что искомого ключа в таблице нет.
Последовательный поиск
Алгоритм последовательного поиска (sequential search) в неупорядоченной таблице
Условия окончания поиска:
Элемент найден, возвращается номер искомого ключа.
Весь массив просмотрен и совпадения не обнаружено, возвращается N+1.
Следует обратить внимание, что если элемент найден, то он найден вместе с минимально возможным индексом, т. е. это первый из таких элементов. Равенство i=N свидетельствует, что совпадения не существует.
Function SeqSearch(x: Tkey; var T: Table): Index;
var i: Index;
begin i:=1;
while (i<=N) and (x<>T[i].key) do i:=i+1;
SeqSearch:=I end;
Время работы зависит от количества сравнений ключей С и параметра успеха S =1 при удаче и 0 при неудаче. Последовательный поиск, реализованный на массиве, производит N сравнений для неуспешного поиска, и в среднем N/2 сравнений для успешного, если мы предположим, что любая из записей имеет равную вероятность быть искомой, то среднее количество сравнений будет: (1+2+...+N)/N = (N+1)/2 N/2
Последовательный поиск с помощью барьерного элемента
Известен очевидный способ улучшения последовательного поиска с помощью барьерного элемента. Здесь использован принцип: если во внутреннем цикле программы проверяются два или более условия, нужно постараться оставить только одно сравнение.
Добавляется фиктивная запись в конец таблицы для хранения искомого ключа.
В цикле выполняется одна проверка
Элемент на позиции N+1 используется как барьерный.
При поиске по большим таблицам скорость улучшенного алгоритма увеличивается на 30% по сравнению с первым вариантом.
Function QSeqSearch(x: Tkey; var T: Table): Index;
var i: Index;
begin i:=1;
T[N+1].key:=x;
while x<>T[i].key do i:=i+1;
QSeqSearch:=i end;
Алгоритм последовательного поиска в упорядоченной таблице
Function SSeqSearch(x: Tkey; var T: Table): Index;
var i: Index;
begin i:=1;
T[N+1].key:=x+1;
while x>T[i].key do i:=i+1;
if x=T[i].key then SSeqSearch:=i
else SSeqSearch:=N+1 end;
При успешном поиске в худшем случае (проверка всех ключей) N и порядка N/2 в среднем. В случае неуспеха поиск может с равной вероятностью закончится на любом из N+1 интервалов, задаваемых N числами: (1 + 2 + … + N + N)/N = (N + 3)/2 и число сравнений также будет порядка N/2. Таким образом, в случае отсутствия искомого элемента алгоритм последовательного поиска в упорядоченной таблице работает вдвое быстрее, чем алгоритм поиска в неупорядоченной таблице.