- •1.Основные понятия эис
- •19. Классификация алгоритмов
- •Классификация Алгоритмов
- •20. Абстрактные типы данных (массивы, связанные списки, выделение памяти)
- •Абстрактные типы данных
- •Элементарные Структуры Данных
- •Массивы
- •Связанные списки
- •Выделение Памяти
- •21. Стеки, очереди, деревья
- •Очереди
- •Деревья
- •Терминология
- •22. Математические характеристики деревьев
- •Свойства
- •23. Обход деревьев
- •Обход Деревьев
- •Алгоритм быстрой сортировки
- •1 2 3 4 5 6 7
- •25. Критерии эффективности алгоритмов (формирование, поиск последовательного масиива)
- •26. Критерии эффективности алгоритма ступенчетого поиска
- •27. Сортировка методом Шелла Сортировка Шелла
- •28. Сортировка простым включением
- •29. Приоритетные очереди
- •30. Радикс сортировка Радикс Сортировка
- •Сортировка Радикс Обменом
- •Прямая Радикс Сортировка
- •Свойства Радикс Сортировок
- •31. Рекурсия Рекурсивные определения
- •Рекурсивные процедуры
- •Итерация и рекурсия
- •32. Рекурсивный обход деревьев, удаление рекурсии Рекурсивный Обход Дерева
- •Удаление Рекурсии
- •33. Элементарные методы сортировки и их характеристики Элементарные Методы Сортировки
- •Правила Игры
- •Сортировка Выбором
- •Сортировка Вставкой
- •34. Простейшие алгоритмы сортировки (методом пузырька, сортировка выбором, шейкер сортировка, ростировка Шелла), сравнение простых методов сортировки. Пузырьковая Сортировка
- •Характеристики Простейших Сортировок
- •Сортировка Файлов с Большими Записями
- •Сортировка Шелла
- •Подсчет Распределения
- •35. Алгоритмы быстрой сортировки, разрядная сортировка Алгоритм быстрой сортировки
- •1 2 3 4 5 6 7
- •36. Пирамидальная сортировка Пирамидальная сортировка
- •37. Сортировка слиянием (простое слияние, двухпутевое слияние, рекурсивный алгоритм слияния) Сортировка слиянием
- •Простое слияние
- •Y 1 2 3 4 5 6 7 8
- •Естественное двухпутевое слияние
- •Рекурсивный алгоритм слияния
1 2 3 4 5 6 7
Здесь также длинная часть подмассива будет равна n-1, поэтому рекурсивный вызов потребуется n раз, что совершенно недопустимо, ввиду ограниченного размера стека. Как это не парадоксально, но алгоритм быстрой сортировки будет плохо работать в данном случае на упорядоченных массивах.
Понятно, что лучшим опорным элементом для массива является медиана, то есть значение, которое разобьет массив на две равные части. Однако поиск медианы может вызвать трудо- и времязатраты, сопоставимые с сортировкой массива.
Хоар предложил два способа улучшить выбор опорного элемента y:
выбирать случайным образом элемент массива,
искать медиану трех случайно взятых элементов массива (средний по величине).
Ахо предлагает выбирать у как наибольшее значение из двух первых элементов массива.
Запишем теперь общий алгоритм, рекурсивно вызывая процедуру сортировки:
procedureQuickSort(varx : vector);procedureSort( l, r : integer);Vari, j : integer; y, z: integer;begini := l; j := r; y := x[(l + r) div 2];repeatwhilex[i] < ydoi := i + 1;whilex[j] > ydoj := j – 1;ifi <= jthenbeginz := x[i]; x[i] := x[j]; x[j] := z; i := i + 1; j := j – 1end;untili > j;ifl < jthenSort (l, j);ifi < rthenSort(i, r)end;
beginSort(1, n)end; {quicksort}
Исключение рекурсии в этом алгоритме достигается использованием стека, в который запоминается запрос на сортировку одной из частей (для простоты – правой).
procedureQuickSort(varx : Vector);vari, j, l, r : integer; y, z: integer; S : Stack;beginPush(s, 1, n);repeatR := Pop(S); L := Pop(S);repeati := l; j := r; y := x[(l + r) div 2];repeatwhilex[i] < ydoi := i + 1;whilex[j] > ydoj := j – 1;ifi<=jthenbeginz := x[i]; x[i] := x[j]; x[j] := z i := i + 1; j := j – 1end;untili > j;ifi < rthenPush( S, i, r) r := j;untill >= r;untilEmpty(S);end; {quicksort}
В стеке было бы рациональнее хранить адрес самой длинной части и продолжать разбиение коротких частей. Этого легко добиться с помощью условия:
ifj – l < r – ithenbeginifi < rthenPush(S, i, r) r := j;endelse beginifl < jthenPush(S, l, j); l := i;end;
Еще один способ улучшения метода, заключается в использовании простых методов для разделенных подмассивов малой длины N. Например, приN= 9, рекомендуется использовать сортировку простой вставкой.
Алгоритм является самым полезным алгоритмом внутренней сортировки, так как требует мало памяти и опережает другие алгоритмы по среднему времени выполнения.
Характеристики алгоритма «быстрой сортировки» зависят от удачного выбора элемента Yдля разбиения. В хорошем случае число сравнений,. Таким образом, быстрая сортировка эффективна лишь в среднем – время работы пропорционально, в худшем случае она может работать очень медленно, пропорционально. Быстрая сортировка не является устойчивой, в отличии, например от простых вставок, слияния списков, простого выбора.
36. Пирамидальная сортировка Пирамидальная сортировка
Принципы пирамидальной сортировки будет проще понять, если рассмотреть два жизненных примера: организацию турнирной таблицы и корпоративную систему выдвижения.
1. Организация турнирной таблицы происходит следующим образом: в первом туре участники разбиты на пары и играют между собой, победители проходят в следующий тур и играют между собой и т.д. В полуфинале участвует 4 участника, в финале 2 и определяется победитель.
Теперь, чтобы определить второго по силе участника, надо вывести из турнира сильнейшего и разыграть турнир заново. Продолжая эту процедуру найдем третьего по силе, четвертого и т.д.
Рассмотрим организацию турнира на примере «участников» - элементов массива (5, 2, 8. 9, 3, 1, 7. 2).
|
|
|
|
|
|
|
9 |
|
|
|
|
|
|
| |||||||||
|
|
|
|
|
|
|
|
|
|
| |||||||||||||
|
|
|
9 |
|
|
|
|
|
|
|
7 |
|
|
| |||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||
|
5 |
|
|
|
9 |
|
|
|
3 |
|
|
|
7 |
| |||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||
5 |
|
2 |
|
8 |
|
9 |
|
3 |
|
1 |
|
7 |
|
2 |
Победителем является «участник» 9. Выведем его из турнира, заменив на «чрезвычайно слабого игрока» -.
|
|
|
|
|
|
|
8 |
|
|
|
|
|
|
| ||||||||
|
|
|
|
|
|
|
|
|
|
| ||||||||||||
|
|
|
8 |
|
|
|
|
|
|
|
7 |
|
|
| ||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| ||||||||
|
5 |
|
|
|
8 |
|
|
|
3 |
|
|
|
7 |
| ||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| ||||
5 |
|
2 |
|
8 |
|
|
3 |
|
1 |
|
7 |
|
2 |
Победителем является «участник» 8. Выведем его из турнира, заменив на «чрезвычайно слабого игрока» -.
|
|
|
|
|
|
|
7 |
|
|
|
|
|
|
| ||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
| ||||||||||||||||||||||
|
|
|
5 |
|
|
|
|
|
|
|
7 |
|
|
| ||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| ||||||||||||||||||
|
5 |
|
|
|
|
|
|
3 |
|
|
|
7 |
| |||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| ||||||||||||||
5 |
|
2 |
|
|
|
3 |
|
1 |
|
7 |
|
2 |
|
|
|
|
|
|
|
5 |
|
|
|
|
|
|
| |||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||||||||||
|
|
|
5 |
|
|
|
|
|
|
|
3 |
|
|
| |||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||||||
|
5 |
|
|
|
|
|
|
3 |
|
|
|
2 |
| ||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||
5 |
|
2 |
|
|
|
3 |
|
1 |
|
|
2 |
И т.д. Таким образом, происходит сортировка посредством выбора из дерева – выбирается максимальный элемент, находящийся в корне дерева.
2. Корпоративная система выдвижения заключается в следующем: из группы простых исполнителей на верхний уровень поднимаются лучшие (например, из группы программистов выдвигаются старшие программисты). Среди старших программистов отбирают руководителей лаборатории. Среди руководителей лаборатории отбирают руководителей отделов и т.д. При этом, когда участник поднимается с самого нижнего уровня, его заменяют «человеком с улицы» (-), а если выдвижение идет с очередного уровня, то его заменяют на лучшего из его подчиненных.
|
|
|
|
|
|
|
9 |
|
|
|
|
|
|
| |||||||||||||||
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||||||
|
|
|
9 |
|
|
|
|
|
|
|
7 |
|
|
| |||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||
|
5 |
|
|
|
9
8 |
|
|
|
3 |
|
|
|
7 |
| |||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||
5 |
|
2 |
|
8 |
|
9 |
|
3 |
|
1 |
|
7 |
|
2 |
В результате получим корпоративную пирамиду, где каждый стоит на своем уровне компетентности.
|
|
|
|
|
|
|
9 |
|
|
|
|
|
|
| |||||||||||||||
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||||||
|
|
|
8 |
|
|
|
|
|
|
|
7 |
|
|
| |||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||
|
5 |
|
|
|
|
|
|
3 |
|
|
|
2 |
| ||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||
|
2 |
|
|
|
|
1 |
|
|
Интуитивно второй способ более удобен – он позволяет избежать лишних сравнений -с -, на которые мы будет то и дело натыкаться в турнирной таблице на поздних стадиях.
Пронумеруем теперь элементы пирамиды по уровням сверху-вниз и слева-направо:
|
|
|
|
|
|
|
X1 |
|
|
|
|
|
|
| |||||||||||
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||
|
|
|
X2 |
|
|
|
|
|
|
|
X3 |
|
|
| |||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||
|
X4 |
|
|
|
X5 |
|
|
|
X6 |
|
|
|
X7 |
| |||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||
X8 |
|
X9 |
|
X10 |
|
X11 |
|
X12 |
|
X13 |
|
X14 |
|
X15 |
Заметим, что отцом k-го узла является узел с номером (kdiv2), а потомками - узлы с номерами 2kи 2k+1. В пирамиде выполнено условие
|
|
|
|
|
Xk div 1 |
|
|
|
|
| |
|
|
Xk |
|
|
|
|
|
|
|
|
|
X2k |
|
|
|
X2k+1 |
|
Очевидным недостатком рассмотренного метода является большое число бесполезных дыр, содержащих -. Было бы очень хорошо организовать пирамиду наNячейках (в нашем случае на 8, а не на 15). Эта цель была реализована Дж. У. Дж. Уильямсом (JohnWilliamJosephWilliams) в 1964 году, разработавшим алгоритм «пирамидальной» сортировки (heap-sort).
Будем называть массив X1,X2,X3 …Xnпирамидой, если выполнено условие:Xj div 2 Xj , при 1jdiv2 <jN.
Тогда X1 X2, X1 X3,X2 X4,X2 X5,и т.д. В частности, наибольший ключ лежит на вершине пирамиды:X1 =max(X1 ,X2,…Xn).
Если удастся каким-либо образом преобразовать массив в пирамиду, то можно будет забрать корень, обменяв его с последним элементов, а затем, уменьшив размер кучи на единицу, воспользоваться нисходящей процедурой построения кучи для корня: на место корня переместить вверх наибольшего из его потомков, затем переместить вверх наибольшего из потомков последнего и т.д.
procedureDownHeap( k : integer);vari, j, t : integer;beginT
:= x[k];whilek <= Countdiv2dobeginj := k + k;ifj < Countthenifx[j] < x[j+1]thenj := j + 1;ift
>= x[j]thenbreak;
x[k] := x[j]; k :=
j;end;
x[k] := t;end;
Применим нисходящую процедуру ко всем элементам, начиная с Ndiv2. А затем, получив кучу, заберем корень, обменяв его с последним элементом, и применим нисходящую процедуру к корню.
Например, для массива 5, 2, 8, 9, 3, 1, 7, 2 алгоритм будет выглядеть следующим образом:
Изобразим массив в виде кучи:
|
|
|
|
|
|
|
5 |
|
|
|
|
|
| |||||||||||||||||||
|
|
|
|
|
|
|
|
|
| |||||||||||||||||||||||
|
|
|
2 |
|
|
|
|
|
|
|
8 |
|
| |||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||||||
|
9 |
|
|
|
3 |
|
|
|
1 |
|
|
|
7 | |||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
Последовательно применим нисходящую процедуру ко всем элементам, имеющим дочерние начиная с конца. Первым будет обработан узел 9 (с индексом 4). При этом никаких изменения в куче не произойдет, так как поддерево 9–2 удовлетворяет условию кучи. Далее обработаем узлы с индексами 3, 2 и 1. Последовательно получаем:
|
|
|
|
|
|
|
5 |
|
|
|
|
|
| |||||||||||||||||||
|
|
|
|
|
|
|
|
|
| |||||||||||||||||||||||
|
|
|
9 |
|
|
|
|
|
|
|
8 |
|
| |||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||||||
|
2 |
|
|
|
3 |
|
|
|
1 |
|
|
|
7 | |||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
|
|
|
|
|
| |||||||||||||||||||
|
|
|
|
|
|
|
|
|
| |||||||||||||||||||||||
|
|
|
9 |
|
|
|
|
|
|
|
8 |
|
| |||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||||||
|
2 |
|
|
|
3 |
|
|
|
1 |
|
|
|
7 | |||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
|
|
|
|
| |||||||||||||||||||
|
|
|
|
|
|
|
|
|
| |||||||||||||||||||||||
|
|
|
5 |
|
|
|
|
|
|
|
8 |
|
| |||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||||||
|
2 |
|
|
|
3 |
|
|
|
1 |
|
|
|
7 | |||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
Получим массив [9, 5. 8, 2. 3, 1, 7, 1], который является кучей.
Обменяем местами корень 9 и последний элемент 2, получим массив 2, 5. 8, 2, 3, 1, 7, 9. При этом 9 стоит уже на своем месте.
|
|
|
|
|
|
|
2 |
|
|
|
|
|
| |||||||||||||||
|
|
|
|
|
|
|
|
|
| |||||||||||||||||||
|
|
|
5 |
|
|
|
|
|
|
|
8 |
|
| |||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||
|
2 |
|
|
|
3 |
|
|
|
1 |
|
|
|
7 | |||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||
9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
Уменьшим размер кучи на 1 и применим нисходящую процедуру к корню 2, получим массив 8, 5, 7, 2, 3, 1, 2, 9.
|
|
|
|
|
|
|
8 |
|
|
|
|
|
| |||||||||||||||
|
|
|
|
|
|
|
|
|
| |||||||||||||||||||
|
|
|
5 |
|
|
|
|
|
|
|
7 |
|
| |||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||
|
2 |
|
|
|
3 |
|
|
|
1 |
|
|
|
2 | |||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||
9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
Обменяем корень с последним элементом, получим массив 2, 5, 7, 2, 3, 1, 8, 9. И т.д.
|
|
|
|
|
|
|
2 |
|
|
|
|
|
| |||||||||||||||
|
|
|
|
|
|
|
|
|
| |||||||||||||||||||
|
|
|
5 |
|
|
|
|
|
|
|
7 |
|
| |||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||
|
2 |
|
|
|
3 |
|
|
|
1 |
|
|
|
8 | |||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||
9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
|
|
|
|
|
| |||||||||||||||
|
|
|
|
|
|
|
|
|
| |||||||||||||||||||
|
|
|
5 |
|
|
|
|
|
|
|
2 |
|
| |||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||
|
2 |
|
|
|
3 |
|
|
|
1 |
|
|
|
8 | |||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||
9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
procedureHeapSort(varx : Vector);vark, t : integer; count : integer;begincount := N;fork := Ndiv2downto1doDownHeap(k);repeatt := x[1]; x[1] := x[count]; x[count] := t; Dec(count); HeapDown(1);untilcount <=1;end;
Время работы пирамидальной сортировки имеет порядок . Пирамидальная сортировка сравнима с сортировкой Шелла или быстрой сортировкой, причем вспомогательной памяти используется мало. С ростомNпирамидальная сортировка превзойдет по скорости сортировку Шелла, но никогда не станет лучше быстрой сортировки. Однако в отличие от быстрой сортировки ее наихудший случай не намного хуже среднего.