- •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
- •Естественное двухпутевое слияние
- •Рекурсивный алгоритм слияния
Y 1 2 3 4 5 6 7 8
Чтобы не запутаться в двух виртуальных массивах, будем использовать один массив двойной длины array[1..2*n]. При этом сначала исходный массив находится в первой половине, в выходной – во второй, а затем наоборот.
Заведем булевскую переменную Up, которая определяет направление слияния: true – из первой половины во вторую, false – из второй половины в первую. Индексы i, j - отвечают за место, из которого берутся элементы для слияния, а k, l – за место куда пересылаются элементы. Переменная Pопределяет длину сливаемых серий (1, 2, 4, …).
Procedure merge(var x: vector);
Var up: boolean;
I, j, k, l: integer;
P: integer;
Begin
Up:=true;
p:=1;
Repeat
if up then
Begin i:=1;j:=n; k:=n+1; l:=2*n; end
Else
Begin i:=n+1; j:=2*n; k:=1; l:=n end;
{слияние p-серии из i, j в к, l}
Up:=not up;
P:=2*p
Until p>=n;
Слияние происходит следующим образом: сначала пересылка идет по адресу k, при этом индекс увеличивается на единицу, затем по адресуl, и индекс уменьшается на 1. Для упрощения будем считать, что пересылка всегда идет по адресуkс шагомh, но после каждого слияния будем чередоватьh(либо +1, либо -1), а также менять местами значенияkиl.
h:=1; m:=n;
Repeat
q:=p; r:=p; m:=m-2*p;
{слияние q элементов из i и r элементов из j}
h:=-h;
{обмен k, l};
Until m=0;
Сама процедура слияния должна предусмотреть копирование оставшегося остатка:
While (q<>0) and(r<>0) do
if x[i]<x[j]
then begin x[k]:=x[i]; k:=k+h; i:=i+1; q:=q-1 end
Else begin x[k]:=x[j]; k:=k+h; j:=j-1; r:=r-1 end;
{копирование остатков из i или j}
Окончательный текст программы
Procedure merge(var x: vector);
Var up: boolean;
I, j, k, l, t: integer;
P, h, q, r, m: integer;
Begin
Up:=true;
p:=1;
Repeat
m:=n; {общее число элементов во входных последовательностях, которые осталось слить}
H:=1;
if up then
Begin i:=1;j:=n; k:=n+1; l:=2*n; end
Else
Begin i:=n+1; j:=2*n; k:=1; l:=n end;
Repeat
if m>= p then q:=p else q:=m; m:=m-q;
if m>= p then r:=p else r:=m; m:=m-r;
While (q<>0) and(r<>0) do
if x[i]<x[j]
then begin x[k]:=x[i]; k:=k+h; i:=i+1; q:=q-1 end
Else begin x[k]:=x[j]; k:=k+h; j:=j-1; r:=r-1 end;
{копирование остатков}
While r<>0 do
Begin
A[k]:=a[j]; k:=k+h; j:=j-1; r:=r-1
End;
While q<>0 do
Begin
A[k]:=a[i]; k:=k+h; i:=i+1; q:=q-1
End;
H:=-h;
T:=k; k:=l; l:=t;
Until m=0;
Up:=not up;
P:=2*p
Until p>=n;
if not up then for i:=1 to n do x[i]:=x[i+n]
End;
Поскольку на каждом проходе pудваивается, то сортировка требует [log2N] проходов. При каждом проходе перемещаются всеNэлементов. Поэтому характеристикаMдля сортировки слиянием оценивается какN*[log2N]. Число сравненийCменьше, чем М, так как при копировании остатков сравнения не проводятся.
Естественное двухпутевое слияние
В случае простого слияния серии формируются из фиксированного числа элементов (2,4,8), при этом никак не учитывается, что данные могут быть уже частично отсортированы естественным образом.
Если сформировать серии таким образом, чтобы они образовывали естественным образом упорядоченные последовательности, то слияние будет выглядеть так:
X1 7 3 6 4 9 8 5
Y1 5 7 8 9 6 4 3
X1 3 4 5 6 7 8 9