
- •Структуры и алгоритмы обработки данных
- •230100.62 – Информатика и вычислительная техника
- •Стандартная постановка задачи
- •Пример постановки задачи
- •Пример постановки задачи в стандартной форме
- •Алгоритмы и их сложность
- •Основы анализа программ
- •Пример анализа алгоритмов
- •Выполнение операторов программы
- •Основы доказательства корректности
- •Динамическое программирование
- •Перемножение нескольких матриц
- •Когда применимо динамическое программирование
- •Наибольшая общая подпоследовательность
- •Жадные алгоритмы
- •Задача о выборе заявок
- •Абстрактные типы данных
- •Атд «Список»
- •Атд «Стек»
- •Атд «Очередь»
- •Множества
- •Хеширование
- •Словари, основанные на хеш-таблицах
- •Поиск слова в тексте
- •Сортировка
- •Сортировка вставками
- •Корневая сортировка
- •Пирамидальная сортировка
- •Переформирование пирамиды
- •Построение пирамиды
- •Сортировка слиянием
- •Управление с помощью таблиц
- •Способы представления графа
- •Матрица смежности
- •Матрица инцидентности
- •Список рёбер
- •Алгоритмы обхода графа
- •Поиск в ширину
- •Задача о кратчайшем пути
- •Алгоритм Дейкстры
- •Алгоритм Беллмана-Форда
- •Задача перекресток
- •Максимальный поток
- •Метод Форда-Фалкерсона
- •Минимальные покрывающие деревья
- •Алгоритм Крускала
- •Алгоритм Прима
- •Минимальные покрывающие деревья
- •Поиск в глубину
- •Топологическая сортировка
- •Деревья
Пирамидальная сортировка
Пирамидальная сортировка (англ. Heapsort, «Сортировка кучей») — алгоритм сортировки, работающий в худшем, в среднем и в лучшем случае (то есть гарантированно) за Θ(n log n) операций при сортировке n элементов. Количество применяемой служебной памяти не зависит от размера массива (то есть, O(1)).
сконструировать пирамиду
for i = 1 to N do
скопировать корень пирамиды в список
переформировать пирамиду
end for
Переформирование пирамиды
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
Построение пирамиды
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
Сортировка слиянием
Сортировка слиянием (англ. 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