Читаем Песни о Паскале полностью

Экспе-риментИскомое числоКоличество шагов поиска
Последовательный поискДвоичный поиск
1502654410
2852882810
373971009
42061529
582276349
6904317710
742571010
833977045
9402188710
1087158159
116811539
12595914110
139288597
1432952610
15953493510
16161886
1710661058
18708198910
192182909
20692795210
Среднее количество шагов4559

Что вы скажете об этом? Двоичный поиск дал превосходный результат, – любое число находится не более чем за 10 шагов! Это любопытно, и побуждает разобраться в алгоритме глубже.

Ах, время, время!

Принимаясь за что-либо, мы прикидываем, сколько времени займет то или иное дело. Поиск может отнять уйму времени, вот почему важно оценить его трудоемкость. Сравним алгоритмы поиска по затратам времени. Только время будем измерять не секундами, а особыми единицами – шагами поиска. Почему? Да потому, что у нас с вами разные компьютеры. Поскольку ваш «станок» мощнее, ту же работу он выполнит быстрее моего, а это нечестно! Мы ведь алгоритмы сравниваем, а не процессоры.

Если улыбнется удача, поиск завершится на первом шаге. Иногда – по закону подлости – тратится максимальное число шагов. Но эти крайние случаи – редкость; обычно поиск занимает какое-то промежуточное время, и наш эксперимент подтвердил это. Программистов интересует время поиска в двух случаях: в худшем, и в среднем (то есть, усредненное по многим случаям).

Начнем с линейного поиска. Очевидно, что в массиве из N элементов худшее время поиска составит N шагов. Что касается среднего времени, то чутье подсказывает, что оно составит половину максимального времени, то есть N/2. Судите сами: искомое число с равной вероятностью может оказаться и ближе и дальше середины массива. Табл. 7 подтверждает эту догадку, – среднее количество шагов там составило 455, что очень близко к значению 1000/2.

Теперь рассмотрим двоичный поиск. Вначале оценим худшее время. Рассудим так. Сколько шагов поиска нужно в массиве из одного элемента? Правильно, один. А теперь вспомним, что при двоичном поиске всякий раз отбрасывается половина оставшегося массива. Значит, посчитав, сколько раз число N делится пополам для получения единицы, мы определим максимальное число шагов. Так и поступим; следите, честно ли я «распилил» нашу тысячу.

1. 1000 / 2 = 500

2. 500 / 2 = 250

3. 250 / 2 = 125

4. 125 / 2 = 62

5. 62 / 2 = 31

6. 31 / 2 = 15

7. 15 / 2 = 7

8. 7 / 2 = 3

9. 3 / 2 = 1

При делении я отбрасывал дробную часть, поскольку в двоичном алгоритме так и делается. Всего потребовалось 9 операций деления. Это значит, что максимальное число шагов поиска равно 10 (с учетом поиска в одном оставшемся элементе). Удивительная прозорливость, – ведь наш эксперимент (табл. 7) показал то же самое!

Теперь оценим среднее время двоичного поиска. Думаете, что оно составит 10/2 = 5 шагов? Как бы ни так! Дело в том, что любой алгоритм поиска в среднем исследует половину массива. Двоичный поиск отбрасывает половину массива на первом же шаге. А это значит, что в среднем число шагов будет всего лишь на единицу меньше худшего, то есть 9. Смотрим в табл. 7, – точно! Наша догадка подтвердилась! Таким образом, двоичный поиск не только быстрее линейного, но и более предсказуем: его худшее время почти не отличается от среднего.

Логарифмы? Это просто!

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

Для таких вычислений математики придумали особую функцию – логарифм (не путайте её с рифмой, ритмом и алгоритмом!). Логарифмы бывают разные: десятичные, натуральные и прочие. Нам интересен двоичный логарифм, который по-научному называется так: «логарифм числа N по основанию два». Математики записывают его следующим образом:

Log2 N

Связь между числом N и его двоичным логарифмом легко проследить на следующих примерах. Слева представлено разложение на множители нескольких чисел, а справа – двоичные логарифмы этих же чисел.

4 = 2 • 2 Log2 4 = 2

16 = 2 • 2 • 2 • 2 Log2 16 = 4

64 = 2 • 2 • 2 • 2 • 2 • 2 Log2 64 = 6

Итак, двоичный логарифм числа равен количеству двоек (ой, нехорошее слово!), перемножаемых для получения этого числа. Например, для получения числа 8 надо перемножить три двойки, и его логарифм равен трем. Кстати, для получения единицы из восьмерки, её тоже «пилят» пополам трижды. Значит, оба способа вычисления логарифма – через умножение, и через деление – равноценны.

Если вы завтра же не забросите программирование, то табл. 8 с логарифмами нескольких чисел ещё пригодится вам.

Табл. 8 – двоичные логарифмы некоторых чисел

NLog2 NNLog2 NNLog2 NNLog2 N
213255129819213
426461024101638414
8312872048113276815
16425684096126553616
Перейти на страницу:

Похожие книги

Сломанная кукла (СИ)
Сломанная кукла (СИ)

- Не отдавай меня им. Пожалуйста! - умоляю шепотом. Взгляд у него... Волчий! На лице шрам, щетина. Он пугает меня. Но лучше пусть будет он, чем вернуться туда, откуда я с таким трудом убежала! Она - девочка в бегах, нуждающаяся в помощи. Он - бывший спецназовец с посттравматическим. Сможет ли она довериться? Поможет ли он или вернет в руки тех, от кого она бежала? Остросюжетка Героиня в беде, девочка тонкая, но упёртая и со стержнем. Поломанная, но новая конструкция вполне функциональна. Герой - брутальный, суровый, слегка отмороженный. Оба с нелегким прошлым. А еще у нас будет маньяк, гендерная интрига для героя, марш-бросок, мужской коллектив, волкособ с дурным характером, балет, секс и жестокие сцены. Коммы временно закрыты из-за спойлеров:)

Лилиана Лаврова , Янка Рам

Современные любовные романы / Самиздат, сетевая литература / Романы