Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Структуры данных / Си структуры данных1.doc
Скачиваний:
47
Добавлен:
23.02.2015
Размер:
1.29 Mб
Скачать

3.7.2. Бинарный поиск

Другим относительно простым методом доступа к элементу является метод бинарного (дихотомического, двоичного) поиска, который выполняется в заведомо упорядоченной последовательности элементов. Записи в таблицу заносятся в лексикографическом (символьные ключи) или численно (числовые ключи) возрастающем порядке. Для достижения упорядоченности может быть использован какой-либо из методов сортировки (см. 3.8).

В рассматриваемом методе поиск отдельной записи с определенным значением ключа напоминает поиск фамилии в телефонном справочнике. Сначала приближенно определяется запись в середине таблицы и анализируется значение ее ключа. Если оно слишком велико, то анализируется значение ключа, соответствующего записи в середине первой половины таблицы, и указанная процедура повторяется в этой половине до тех пор, пока не будет найдена требуемая запись.

Если значение ключа слишком мало, испытывается ключ, соответствующий записи в середине второй половины таблицы, и процедура повторяется в этой половине. Этот процесс продолжается до тех пор, пока не будет найден требуемый ключ или не станет пустым интервал, в котором осуществляется поиск.

Для того чтобы найти нужную запись в таблице, в худшем случае требуется log2(N) сравнений. Это значительно лучше, чем при последовательном поиске.

Программная иллюстрация бинарного поиска в упорядоченном массиве приведена в следующем примере, где mas- исходный массив, key - ключ, который ищется; функция возвращает индекс найденного элемента или EMPTY - если элемент отсутствует в массиве.

{===== Программный пример 3.5 =====}

int BinSearch( int* mas, int key )

{

int first = 0, last = N-1; // начальные границы интервала

int i;

while(first <= last ){ // пока интервал поиска не равен 0

i = (first + last) / 2; // середина интервала

if( mas[i] == key ) return i; // ключ найден, возврат

else {

if( mas[i] < key )

first = i + 1;//поиск в правом подинтервале

else last = i - 1; // поиск в левом подинтервале

}

}

return EMPTY; // ключ не найден

}

Трассировка бинарного поиска ключа 275 в исходной последовательности:

75, 151, 203, 275, 318, 489, 524, 519, 647, 777

представлена в табл. 3.4.

Таблица 3.4

Итерация

first

last

i

K[i]

1

2

3

4

0

0

2

3

9

3

3

3

4

1

2

3

318

151

203

275

Алгоритм бинарного поиска можно представить и несколько иначе, используя рекурсивное описание. В этом случае граничные индексы интервала firstиlastявляются параметрами алгоритма.

Рекурсивная процедура бинарного поиска представлена в программном примере 3.6. Для выполнения поиска необходимо при вызове процедуры задать значения ее формальных параметров firstиlast- 1 и N соответственно, гдеfirst,last- граничные индексы области поиска.

{===== Программный пример 3.6 =====}

int BinSearch( int* mas, int key, int first, int last )

{

if(first > last ) return EMPTY; // ключ не найден

int i = (first + last) / 2; // середина интервала

if( mas[i] == key ) return i; // ключ найден, возврат

else

{

if( mas[i] < key )

return BinSearch( mas, key,

i + 1, last ); // поиск в правом подинтервале

else return BinSearch( mas, key,

first, i - 1 );// поиск в левом подинтервале

}

}

Известно несколько модификаций алгоритма бинарного поиска, выполняемых на деревьях, которые будут рассмотрены в главе 5.