Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конспект лекций СиАОД.docx
Скачиваний:
9
Добавлен:
01.03.2025
Размер:
4.62 Mб
Скачать
    1. Пирамидальная сортировка

Пирамидальная сортировка (англ. Heapsort, «Сортировка кучей») — алгоритм сортировки, работающий в худшем, в среднем и в лучшем случае (то есть гарантированно) за Θ(n log n) операций при сортировке n элементов. Количество применяемой служебной памяти не зависит от размера массива (то есть, O(1)).

  • сконструировать пирамиду

  • for i = 1 to N do

  • скопировать корень пирамиды в список

  • переформировать пирамиду

  • end for

      1. Переформирование пирамиды

FixHeap (list, root, key, bound)

List сортируемый список / пирамида

Root номер корня пирамиды

key ключевое значение, вставляемое в пирамиду

bound правая граница (номер) в пирамиде

vacant = root

while 2 * vacant < = bound do

largerChild = 2 * vacant

// поиск наибольшего из двух непосредственных потомков

if ( largerChild < bound ) and ( list [largerChild + 1 ] > list [largerChild ] then

largerChild = largerChild + 1

end if

// находится ли ключ выше текущего потомка?

if key > list [largerChild ] then

// да, цикл завершается

break

else

// нет, большего непосредственного потомка следует поднять

list [ vacant ] = list [largerChild ]

vacant = largerChild

end if

end while

list [ vacant ] = key

      1. Построение пирамиды

for i = N / 2 down to 1 do

FixHeap {list, i, list [ i ], N )

end for

Окончательный алгоритм

for i = N / 2 down to 1 do

FixHeap {list, i, list [ i ], N )

end for

for i = N down to 2 do

max = list [ i ]

FixHeap (list, i, list [ i ], i - 1 )

List [ i ] = max

end for

    1. Сортировка слиянием

Сортировка слиянием (англ. merge sort) — алгоритм сортировки, который упорядочивает списки (или другие структуры данных, доступ к элементам которых можно получать только последовательно, например — потоки) в определённом порядке. Эта сортировка — хороший пример использования принципа «разделяй и властвуй». Сначала задача разбивается на несколько подзадач меньшего размера. Затем эти задачи решаются с помощью рекурсивного вызова или непосредственно, если их размер достаточно мал. Наконец, их решения комбинируются, и получается решение исходной задачи.

Пример сортировки слиянием. Сначала делим список на кусочки (по 1 элементу), затем сравниваем каждый элемент с соседним, сортируем и объединяем. В итоге, все элементы отсортированы и объединены вместе.

Для решения задачи сортировки эти три этапа выглядят так:

Сортируемый массив разбивается на две части примерно одинакового размера;

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

Два упорядоченных массива половинного размера соединяются в один.

1.1. - 2.1. Рекурсивное разбиение задачи на меньшие происходит до тех пор, пока размер массива не достигнет единицы (любой массив длины 1 можно считать упорядоченным).

3.1. Cоединение двух упорядоченных массивов в один.

Основную идею слияния двух отсортированных массивов можно объяснить на следующем примере. Пусть мы имеем два подмассива. Пусть также, элементы подмассивов в каждом из этих подмассивов отсортированы по возрастанию. Тогда:

3.2. Слияние двух подмассивов в третий результирующий массив.

На каждом шаге мы берём меньший из двух первых элементов подмассивов и записываем его в результирующий массив. Счетчики номеров элементов результирующего массива и подмассива из которого был взят элемент увеличиваем на 1.

3.3. "Прицепление" остатка.

Когда один из подмассивов закончился, мы добавляем все оставшиеся элементы второго подмассива в результирующий массив.

MergeSort (list, first, last )

list сортируемый список элементов

first номер первого элемента в сортируемой части списка

last номер последнего элемента в сортируемой части списка

if first < last then

middle = (first + last ) / 2

MergeSort (list, first, last )

MergeSort (list, first, last )

MergeSort (list, first, last )

MergeLists (list, first, middle, middle + 1, last)

end if

MergeLists (list, start1, end1, start2, end2)

list упорядочиваемый список элементов

start1 начало списка «А»

end1 конец списка «А»

start2 начало списка «В»

end2 конец списка «В»

// предполагается, что элементы списков А и В следуют в списке list друг за другом

finalStart = start1

finalEnd = end2

indexC = 1

while (start1 <= end1 ) and (start2 <= end2) do

if list [start1] <= list [ start2 [ then

result [ indexC] = list [ start1 ]

start1 = start1 + 1

else

result [ indexC] = list [ start2 ]

start2 = start2 + 1

end if

indexC = indexC + 1

end while

// перенос оставшейся части списка

if ( start1 <= end1) then

for i = start1 to end1 do

result [ indexC] = list [ i ]

indexC = indexC + 1

end for

else

for i = start2 to end2 do

result [ indexC] = list [ i ]

indexC = indexC + 1

end for

end if

//возвращение результатов в список

indexC = 1

for i = finalStart to finalEnd do

list [ i ] = result [ indexC]

indexC = indexC + 1

end for