Лабораторная работа №5: Алгоритмы сортировки
Цель работы:
Изучить основные алгоритмы сортировки, реализовать их на языке Python и сравнить их поведение на массивах разной структуры и размера. В ходе работы необходимо рассмотреть как элементарные квадратичные методы сортировки, так и более эффективные алгоритмы, основанные на подходе «разделяй и властвуй», а также исследовать устойчивость сортировки, число сравнений, число обменов и влияние входных данных на эффективность алгоритмов.
Задание 1. Реализация элементарных алгоритмов сортировки
Рассматривается задача упорядочивания результатов автоматической проверки работ студентов. Для каждого студента известен числовой балл, и необходимо отсортировать список результатов по возрастанию. Требуется реализовать на языке Python три базовых алгоритма сортировки, изученные в лекциях: сортировку пузырьком, сортировку выбором и сортировку вставками.
Для проведения экспериментов используйте следующие наборы данных:
data_random = [57, 12, 89, 34, 76, 11, 90, 43, 65, 28, 71, 5, 39, 84, 22]
data_sorted = [5, 11, 12, 22, 28, 34, 39, 43, 57, 65, 71, 76, 84, 89, 90]
data_reverse = [90, 89, 84, 76, 71, 65, 57, 43, 39, 34, 28, 22, 12, 11, 5]
data_almost_sorted = [5, 11, 12, 22, 28, 34, 43, 39, 57, 65, 71, 76, 84, 89, 90]
Необходимо разработать программу, которая для каждого из трёх алгоритмов выполняет сортировку указанных последовательностей и выводит исходный массив, отсортированный массив, число сравнений, число обменов, для пузырьковой сортировки, и число сдвигов, для сортировки вставками, а также число проходов внешнего цикла по массиву.
После выполнения необходимо объяснить, как в пузырьковой сортировке максимальный элемент постепенно перемещается в конец неотсортированной части, почему сортировка выбором делает меньше обменов, чем пузырьковая, и почему сортировка вставками может работать заметно лучше на почти упорядоченных данных. Также сделайте вывод о различии между этими тремя алгоритмами с точки зрения внутреннего механизма работы.
Задание 2. Улучшения пузырьковой сортировки
После изучения базовой пузырьковой сортировки необходимо рассмотреть её модификации, направленные на уменьшение количества лишних проходов и на более быстрое перемещение элементов к своим позициям. Требуется реализовать сортировку перемешиванием и гномью сортировку.
Для эксперимента используйте массивы, в которых часть элементов уже находится почти на своих местах:
data1 = [1, 2, 3, 4, 6, 5, 7, 8, 9, 10]
data2 = [2, 1, 3, 4, 5, 6, 7, 8, 10, 9]
data3 = [1, 3, 2, 4, 5, 7, 6, 8, 10, 9]
data4 = [10, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Для каждого массива программа должна выводить исходную последовательность, результат сортировки, число сравнений, число перестановок и число проходов (для сортировки перемешиванием)/ число шагов (для гномьей сортировки).Также необходимо сравнить результаты работы этих двух алгоритмов с обычной пузырьковой сортировкой на тех же наборах данных.
После выполнения необходимо объяснить, почему сортировка перемешиванием считается улучшением пузырьковой сортировки, какую роль играют границы left и right, и за счёт чего двусторонний проход позволяет быстрее перемещать как большие элементы вправо, так и маленькие элементы влево. Также необходимо объяснить логику гномьей сортировки и сделать вывод о том, почему оба этих метода всё равно сохраняют квадратичную природу, несмотря на локальные улучшения.
Задание 3. Сортировка слиянием: рекурсивный и итерационный варианты
Рассматривается задача сортировки данных о грузах на складе. Для каждого контейнера известен числовой приоритет обработки. Необходимо упорядочить контейнеры по возрастанию приоритета и исследовать работу алгоритма сортировки слиянием в двух вариантах: рекурсивном и итерационном. При итерационном проходе используйте дополнительный массив.
Для эксперимента используйте следующий массив:
cargo_priority = [42, 17, 93, 58, 11, 76, 24, 65, 39, 88, 5, 71, 30, 54, 19, 93, 7, 80, 80, 48, 77, 98, 97, 56, 27, 94, 73, 74, 72, 47, 95, 70, 96, 93, 84, 53, 38, 90, 94, 85, 34, 88, 56, 29, 65, 84, 72, 60, 63, 59, 61, 61, 14, 42, 89, 97, 62, 27, 19, 36, 18, 89, 3, 64, 99, 38, 26, 99, 55, 40, 32, 99, 86, 44, 1, 100, 53, 74, 78, 68, 21, 24, 85, 32, 99, 68, 85, 12, 4, 18, 69, 46, 46, 50, 64, 7, 68, 27, 98, 77, 41, 76, 12, 12, 62, 75, 29, 52, 12, 91, 73, 14, 22, 47, 47, 16, 25, 64, 54, 66, 89, 20, 68, 82, 4, 7, 58, 42, 13, 3, 60, 10, 52, 25, 98, 64, 86, 48, 44, 38, 2, 33, 14, 28, 29, 40, 23, 83, 47, 35]
Необходимо реализовать оба варианта сортировки слиянием и вывести исходный массив, отсортированный массив, число сравнений, максимальную глубину рекурсии для рекурсивной версии и число проходов для итерационной версии.
После выполнения необходимо объяснить, как именно массив разбивается на подпоследовательности в рекурсивной версии, в каком порядке происходит обратное слияние частей и чем восходящий итерационный вариант отличается от рекурсивного по логике выполнения. Также следует сделать вывод о том, почему сортировка слиянием требует дополнительной памяти, но при этом обеспечивает гарантированно хорошую асимптотическую сложность.
