1. Метод пузырька
Алгоритм довольно очевиден. Рассмотрим работу алгоритма на примере файла из 16 элементов:
исх. проход 1 проход 4 проход 7
файл │ проход 2 │ проход 5 │ проход 8
│ │ │ проход 3 │ │ проход 6 │ │ проход 9
│ │ │ │ │ │ │ │ │ │
703 ┌─>908 908 908 908 908 908 908 908 908
765 │ 703 ┌>897 897 897 897 897 897 897 897
677 │ 765 │ 703 ┌>765 703 703 703 703 703 703
612 │ 677 │ 765──┘ 703 765 765 765 765 765 765
509 │ 612 │ 677 677 677 677 677 677 677 677
154 │ 509 │ 612 ┌>653 653 653 653 653 653 653
426 │ 154 │ 509 │ 612 612 612 612 612 612 612
653 │ 426 │ 154 │ 509 ┌─>512 512 512 512 512 512
275 │ 653 │ 426 │ 154 │ 509 509 509 509 509 509
897 │ 275 │ 653──┘ 426 │ 154 ┌>503 503 503 503 503
170 │ 897──┘ 275 ┌>512─┘ 426 │ 154 ┌>426 426 426 426
908─┘ 170 ┌─>512──┘ 275 ┌>503─┘ 426─┘ 154 ┌>275 275 275
61 ┌─>512─┘ 170 503──┘ 275 275 275─┘ 154 ┌>170 170
512─┘ 61 ┌─>503 170 170 170 170 170─┘ 154 154
87 ┌─>503─┘ 61 ┌>87 87 87 87 87 87 87
503─┘ 87 87 ──┘ 61 61 61 61 61 61 61
Пары стоящих рядом элементов просматриваются в направлении снизу вверх и сравниваются. Если верхний элемент оказывается меньше нижнего по рисунку, то они меняются местами. Продолжая этот процесс циклически, мы в конце концов придем к отсортированному файлу.Файл расположен вертикально снизу вверх, чтобы эффект всплывающего пузырька выглядел более наглядно. Элементы с большим значением ключа "всплывают" наверх, после последовательных сравниваний с соседними элементами.
Алгоритм имеет следующий вид.
b=N;
while ( b ╪ 0 )
┌───────────────────────────────────────────┐
│ t=0; │
│ for j=1 to b-1 do │
│┌────────────────────────────────────────┐ │
││ ┌───────────────┐ │ │
││ │ │ │ │ через <-> обозначена
││ if ( k[j] > k[j+1] ) │ k[j]<->k[j+1]│ │ │ операция обмена
││ │ t=j; │ │ │ значениями двух
││ └───────────────┘ │ │ переменных
│└────────────────────────────────────────┘ │
│ b=t; │
└───────────────────────────────────────────┘
Время работы алгоритма t примерно оценивается формулой:
t=a*N¤ + b*N
где a,b - неизвестные константы, зависящие от программной реализа-
ции алгоритма.
2. Быстрая сортировка.
Основная стратегия ускорения алгоритмов сортировка - обмены между как можно более дальними элементами исходного файла - в методе быстрой сортировки реализована за счет того, что один из ключей в исходном файле используется для разделения его на два подфайла так, чтобы слева от выбранного элемента находились только элементы с меньшими ключами, а справа - только с большими. Элемент, разделяющий файл, помещается между его двумя подфайлами и процедура выполняется рекурсивно для каждой половины до тех пор, пока в очередном новом подфайле не окажется меньше, чем М элементов, где М - заранее выбранное число.
Рассмотрим схему алгоритма.
l=1;r=N;
║
╔>═╬══════<══════════════════════════════════════════════════════════╗
║ if(r-l < M) ┌─────────────────────────────────────────────────────┐║
║ ║ │ Отсортировать часть файла K[l] ... K[r] простыми │║
║ ║ │ вставками │║
║ ║ │ if (стек пуст) Конец алгоритма. │║
║ ║ │ ┌─────────────────────────────────┐ │║
║ ║ │ else │взять из стека элемент (l',r') ╞>═╪╝
║ ║ │ │l=l' ; r=r' ; │ │
║ ║ │ └─────────────────────────────────┘ │
║ ║ └─────────────────────╥───────────────────────────────┘
║ ╚>═╦═<═══════════════════════════╝
║ ┌───╨──────┬─────────┐
║ │Выбор Х │ X=K[l]; │
║ └──────────┴─────────┘
║ i=l; j=r;
║ ║
║ ╠═══════════<════╦═══<═══════ ═>══╦════════<═══════╗
║ if(X<K[j]) j=j-1═>╝ if(X>K[i]) i=i+1═>╝
║ ┌────────────────┐ ┌───────────────┐
║ if(j>i)│K[i]=K[j];i=i+1;╞═>═ if(j>i) │K[j]=K[i];j=j-1│
║ └────────────────┘ └╥──────────────┘
║ else K[i]=X ═>═╗ ══<════════════╝
║ ║ else K[j]=X;i=j;═>╗
║ ║ ║
║ ┌────────╨────────────────────────────────────────────╨───┐
║ else │ Поместить в стек большую половину файла: либо (l,i-1), │
║ │ либо (i+1,r) и установить для оставшейся половины либо │
║ │ l=i+1, либо r=i-1 соответственно. │
║ └───────────────────────────────────────╥─────────────────┘
╚═════════════════════════════════<════════════════╝
Сортировка подфайлов, содержащих меньше чем М элементов, выполняется каким-либо простым методом, например простыми вставками. Таким образом, реализация метода зависит от двух параметров: значения М и способа выбора элемента, который предназначен для разделения файла на две части.
Блок выбора Х в простейшем случае формулируется как X=K[l], однако это может привести к крайне неэффективному алгоритму. Наиболее простое лучшее решение - выбирать Х как случайный ключ из диапазона K[l] ... K[r] и обменять его с K[l].
Ниже быстрая сортировка проиллюстрирована примером файла из 16 элементов. Квадратными скобками [] выделены подфайлы, подлежащие последующей сортировке. В рамку взяты элементы, принятые на данном шаге за Х. M принято за 1 - наименьшее возможное значение, то есть в данном случае алгоритм не переходит к другому методу для коротких отрезков, меньших M. Для первого шага показаны направления пересылки в соответствии со схемой алгоритма. Числа на линиях определяют поря док, в котором выполняются пересылки.
N │
шага│ Состояние файла
────┼─────────────────────────────────────────────────────────────────
│ ┌──<─5───────┐
│ │┌─>─4───────┼──────┐
│ ┌──<─3─┼┼───────────┼──────┼┐
│ │┌─>─2─┼┼───────────┼──────┼┼───┐
│ ┌─<─1──┼┼─────┼┼───────────┼──────┼┼──┐│
│ ┌─┴─┐ ││ ││ ┌>─6┐│ ││ ││
исх.│ │503│ 87 512 61 908 170 897 275 653 426 154 509 612 677 765 703
│ └───┘
│┌ ┌───┐ ┐ ┌ ┐
1 ││ │154│ 87 426 61 275 170│503│897 653 908 512 509 612 677 765 703│
│└ └───┘ ┘ └ ┘
│┌ ┌──┐ ┐ ┌ ┐ ┌ ┐
2 ││ │61│ 87│154│426 275 170│503│897 653 908 512 509 612 677 765 703│
│└ └──┘ ┘ └ ┘ └ ┘
│ ┌ ┌───┐ ┐ ┌ ┐
3 │ 61 87 154│ │426│ 275 170│503│897 653 908 512 509 612 677 765 703│
│ └ └───┘ ┘ └ ┘
│ ┌ ┌───┐ ┐ ┌ ┐
4 │ 61 87 154│ │170│ 275│426 503│897 653 908 512 509 612 677 765 703│
│ └ └───┘ ┘ └ ┘
│ ┌ ┌───┐ ┐
5 │ 61 87 154 170 275 426 503│ │897│ 653 908 512 509 612 677 765 703│
│ └ └───┘ ┘
│ ┌ ┌───┐ ┐
6 │ 61 87 154 170 275 426 503│ │703│ 653 765 512 509 612 677│ 897 908
│ └ └───┘ ┘
│ ┌ ┌───┐ ┐
7 │ 61 87 154 170 275 426 503│ │677│ 653 612 512 509 │ 703 765 897 908
│ └ └───┘ ┘
│ ┌ ┌───┐ ┐
8 │ 61 87 154 170 275 426 503│ │509│ 653 612 512 │ 677 703 765 897 908
│ └ └───┘ ┘
│ ┌ ┌───┐ ┐
9 │ 61 87 154 170 275 426 503 509│ │653│ 612 512 │ 677 703 765 897 908
│ └ └───┘ ┘
│ ┌ ┌───┐ ┐
10 │ 61 87 154 170 275 426 503 509│ │512│ 612 │ 653 677 703 765 897 908
│ └ └───┘ ┘
│
10 │ 61 87 154 170 275 426 503 509 512 612 653 677 703 765 897 908
│
