Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методы_new1 (2).doc
Скачиваний:
0
Добавлен:
11.02.2026
Размер:
197.59 Кб
Скачать

Двоичный поиск (дихотомия)

Перед применением алгоритма двоичного поиска массив обязательно должен быть отсортирован.

В первом цикле делим весь наш исходный отсортированный массив пополам и сравниваем ключ поиска со средним значением (по которому делили массив).

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

В следующем цикле выбранную часть массива также делим пополам и, как и в предыдущем цикле выполняем сравнение.

В случае, если ключ поиска не совпал с центральным элементом, выбираем нужную часть и в следующем цикле будем уже работать с ней.

Т.е. после каждого сравнения отсекается ровно половина, сокращая тем самым область поиска.

Так продолжается до тех пор, пока значение центрального элемента не совпадет с ключом поиска, либо не исчерпаются все элементы в получаемых подмассивах.

Для поиска в массиве, состоящем из 1024 элементов, потребуется максимум 10 сравнений, т.к. деление будет происходить так: 512, 256, 128, 64, 32, 16, 8, 4, 2, 1.

Посчитать максимальное количество сравнений можно и таким образом: представим 1024 как 2 в 10-й степени.

Число степени и будет нам говорить о количестве максимальных сравнений.

К примеру, в массиве из 1 048 576 (2 в 20-й степени) элементов, нужно выполнить как максимум только 20 сравнений.

Если брать в сравнение этот вид поиска и линейный поиск, то в массиве из 1 048 576 элементов, нужно было бы выполнить в среднем 1 048 576 / 2 сравнений, а это целых 524 288.

Программа, реализующая алгоритм двоичного поиска в массиве:

template<class T>

int binarySearch (T a[], int size, T key ) { int low=0, int high=size-1;

//выделяем место в памяти для переменной, которая будет //у нас сохранять значение середины массива int middle;

//цикл двоичного поиска //цикл длится, пока между границами массива есть значения while (low <= high) {

middle = (low + high) / 2;

//если найден ключ поиска, то возвращаем его индекс if (key == a[middle])

return middle;

//в случае, если не найден ключ поиска, и его значение меньше //среднего значения, меняем верхнюю границу массива, тем самым //отсекая половину с большими значениями, в которой точно искать //нечего else if (key < a[middle])

high = middle - 1;

//в случае, если не найден ключ поиска, и его значение больше //среднего значения, меняем нижнюю границу массива, тем самым //отсекая половину с меньшими значениями else

low = middle + 1;

}

//если ключ поиска не найден в массиве, то возвращаем -1 return -1;

}

Результат работы некоторой программы:

 

 

Как мы видим, по результатам работы программы ищем число 4 (ключ поиска).

В первой итерации определяется середина массива, значением является число 14. Происходит сравнение ключа поиска с этим значением и, в случае несоответствия, продолжается поиск.

Целью поиска выбирается подмассив меньших значений, т.к. ключ поиска 4 меньше 14.

Во второй итерации выведен этот подмассив.

Теперь серединой выбрано значение 6 - оно также не совпадает с ключом поиска, которое меньше 6.

И опять, в разделенном пополам массиве также выбирается подмассив с меньшими значениями.

Его мы видим в третьей итерации.

На данном этапе подмассив уже состоит всего - лишь из трех значений, серединой выбирается 2.

Сравниваем с ключом - не совпадает, 4 больше, чем 2, а значит, поиск на следующей итерации будет проходить в подмассиве с большими значениями.

На четвертой итерации мы видим, что подмассив состоит из всего - лишь из одного числа, которое выбирается серединой, выполняется проверка и находится ключ.

Выводится сообщение, что ключ поиска найден в элементе массива с индексом 2.

В данном примере было использовано максимальное число сравнений, равное четырем. Как вы уже знаете, максимальным числом возможных сравнений является степень числа 2, возведя в которую мы получим размер массива.