
А) сортировки сравнениями (сортировка вставками, пирамидальная сортировка, быстрая сортировка);Сортировка вставками (insertion sort)
Алгоритм состоит в том, что на i-ом этапе элемент a[i] вставляется в нужную позицию среди элементов a[1]… a[i-1].
Поиск
места вставки требует
операций, сдвиг всех после вставленного
элемента
,
т.е. сравнений
Пирамидальная
сортировка. Массив
с индексами 1, …,n
называется кучей (имеет структуру кучи),
если для любого индекса k
выполняются неравенства
и
Соответствие между геометрической структурой пирамиды как дерева и массивом устанавливается по следующей схеме: в a[0] хранится корень дерева; левый и правый сыновья элемента a[i] хранятся, соответственно в a[2i] и a[2i+1] 1. Построение кучи.Рассмотрим правую половину исходного массива. В ней куча уже построена, т.к. : k = 2i( или k = 2i+1 ) находятся за границей массива. Далее будем расширять часть массива с этим свойством, добавляя по одному элементу за шаг. Следующий элемент на каждом шаге добавления - тот, который стоит перед уже готовой частью. Если a[i] не удовлетворяет условию, то меняем его местами с наибольшими из потомков, если неравенства выполняются, то процедура просеивания заканчивается, иначе повторяем процедуру. Когда неравенства выполняются, то куча наращивается, и берём следующий элемент.
На
каждом шаге не более чем
действий. 2.
Построение отсортированного массива
с использованием полученной кучи:
1) меняем местами первый и последний элементы
2) осуществляем процедуру просеивания первого элемента через первые N-1 элементов массива.
3)
меняем местами 1 и N-1
элементы и осуществляем просеивание
1-ого элемента через первые N-2
элементов и т.д.
операций.
Т.е.
сортировка кучей имеет сложность
.
Быстрая сортировка
-
из массива выбирается некоторый опорный элемент a[i] (первый элемент, последний элемент, средний элемент, произвольный элемент)
-
запускается процедура разделения массива, которая перемещает все ключи, меньшие, либо равные a[i], влево от него, а все ключи, большие, либо равные a[i] - вправо,
-
теперь массив состоит из двух подмножеств, причем левое меньше, либо равно правого,
-
для обоих подмассивов, если в подмассиве более двух элементов, рекурсивно запускаем ту же процедуру.Среднее время работы быстрой сортировки
б) карманная сортировка как пример распределяющей сортировки;
Ключ, по которому происходит сортировка, необходимо разделить на части, разряды ключа. Например, слово можно разделить по буквам, число - по цифрам...
До сортировки необходимо знать два параметра: k и m, где k - количество разрядов в самом длинном ключе, m - разрядность данных: количество возможных значений разряда ключа
При сортировке русских слов m = 33, так как буква может принимать не более 33 значений. Если в самом длинном слове 10 букв, k = 10.
Аналогично, для для шестнадцатиричных чисел m=16, если в качестве разряда брать цифру, и m=256, если использовать побайтовое деление.
Эти параметры нельзя изменять в процессе работы алгоритма.
Предположим, что элементы линейного списка L есть k-разрядные десятичные числа, разрядность максимального числа известна заранее. Обозначим d(j,n) - j-ю справа цифра числа n, которую можно выразить как
Пусть
- вспомогательные списки (карманы),
вначале пустые. Поразрядная сортировка
состоит из двух процессов, называемых
распределение и сборка и выполняемых
для j=1,2,...,k.
Фаза
распределения разносит элементы L по
карманам: элементы
списка L последовательно добавляются
в списки
,
где
.
Таким образом, получаем десять списков,
в каждом из которых j-тые разряды чисел
одинаковы и равны m.
Фаза
сборки состоит в объединении списков
в общий список
Рассмотрим пример работы алгоритма на входном списке 0 => 8 => 12 => 56 => 7 => 26 => 44 => 97 => 2 => 37 => 4 => 3 => 3 => 45 => 10.
Максимальное число содержит две цифры, значит, разрядность данных k=2.
Первый
проход, j=1.
Распределение
по первой справа цифре:
:
0 => 10 // все
числа с первой справа цифрой 0
:
пусто;
:
12 => 2;
:
3 => 3;
:
44 => 4;
:
45;
:
56 => 26;
:
7 => 97 => 37;
:
8
:
пусто //
все числа с первой справа цифрой
9
Cборка:
соединяем
списки
один за другим
L: 0 => 10 => 12 => 2 => 3
=> 3 => 44 => 4 => 45 => 56 => 26 => 7 => 97
=> 37 => 8
Второй проход, j=2.
Распределение
по второй справа цифре:
:
0 => 2 => 3 => 3 => 4 => 7 => 8
:
10 => 12;
:
26 ;
:
37;
:
44 => 45;
:
56;
:
пусто;
:
пусто;
:
пусто;
:
97; Cборка:
соединяем списки
Li один за другим
L: 0 => 2 => 3 => 3 => 4
=> 7 => 8 => 10 => 12 => 26 => 37 => 44 => 45
=> 56 => 97
Число используемых карманов - количество возможных значений элемента списка. Сортировку можно организовать так, чтобы не использовать дополнительной памяти для карманов, т.е элементы списка не перемещать, а с помощью перестановки указателей присоединять их к тому или иному карману.
Алгоритм поразрядной сортировки по символьным строкам фиксированной длинны для списка из n записей, выполняется за время O(n).