Программирование на языке Pascal




Сортировка бинарными вставками - часть 2


Как видим, правая граница становится неопределенной - выходит за пределы массива. Будет ли этот факт иметь какие-либо неприятные последствия? Очевидно, нет, поскольку нас интересует не правая, а левая граница.

"А что будет, если мы захотим добавить 21?" - спросит особо въедливый читатель. Проверим это:

2 4 6 8 10 [12 14 16 18] 2 4 6 8 10 12 14 [16 18] 2 4 6 8 10 12 14 16 [18] 2 4 6 8 10 12 14 16 18][

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

Вспомним, однако, что в реальности на (N+1)-й позиции как раз и находится вставляемый элемент (21). Таким образом, если левая граница вышла за рассматриваемый диапазон, получается, что ничего сдвигать не нужно. Вообще же такие действия выглядят явно лишними, поэтому от них стоит застраховаться, введя одну дополнительную проверку в текст алгоритма.

Реализация алгоритма БинВст

for i:= 2 to n do if a[i-1]>a[i] then begin x:= a[i]; left:= 1; right:= i-1; repeat sred:= (left+right)div 2; if a[sred]<x then left:= sred+1 else right:= sred-1; until left>right; for j:= i-1 downto left do a[j+1]:= a[j]; a[left]:= x; end;

Эффективность алгоритма БинВст

Теперь на каждом шаге выполняется не N, а log N проверок5), что уже значительно лучше (для примера, сравните 1000 и 10 = log 1024). Следовательно, всего будет совершено N*log N сравнений. Впрочем, улучшение это не слишком значительное, ведь по количеству пересылок наш алгоритм по-прежнему имеет сложность "порядка N2".




Содержание  Назад  Вперед