Сравнительный анализ алгоритмов
Сортировка вставками:
Рассмотрим работу алгоритма сортировки вставками на массиве [8, 3, 5, 1, 7, 2, 6, 4]:
Шаг 1 (элемент с индексом 1, значение 3) Сравниваем с предыдущим (8): 3 < 8 → меняем местами. Получаем: [3, 8, 5, 1, 7, 2, 6, 4] Первые два элемента отсортированы.
Шаг 2 (элемент с индексом 2, значение 5) Сравниваем с 8: 5 < 8 → меняем → [3, 5, 8, 1, 7, 2, 6, 4] Сравниваем с 3: 5 > 3 → останов. Теперь первые три элемента: [3, 5, 8] — отсортированы.
Шаг 3 (элемент с индексом 3, значение 1) Сравниваем с 8: 1 < 8 → меняем → [3, 5, 1, 8, 7, 2, 6, 4] Сравниваем с 5: 1 < 5 → меняем → [3, 1, 5, 8, 7, 2, 6, 4] Сравниваем с 3: 1 < 3 → меняем → [1, 3, 5, 8, 7, 2, 6, 4] Дальше элементов слева нет. Первые четыре элемента: [1, 3, 5, 8] — отсортированы.
Шаг 4 (элемент с индексом 4, значение 7) Сравниваем с 8: 7 < 8 → меняем → [1, 3, 5, 7, 8, 2, 6, 4] Сравниваем с 5: 7 > 5 → останов. Первые пять элементов: [1, 3, 5, 7, 8] — отсортированы.
Шаг 5 (элемент с индексом 5, значение 2) Сравниваем с 8: 2 < 8 → меняем → [1, 3, 5, 7, 2, 8, 6, 4] Сравниваем с 7: 2 < 7 → меняем → [1, 3, 5, 2, 7, 8, 6, 4] Сравниваем с 5: 2 < 5 → меняем → [1, 3, 2, 5, 7, 8, 6, 4] Сравниваем с 3: 2 < 3 → меняем → [1, 2, 3, 5, 7, 8, 6, 4] Сравниваем с 1: 2 > 1 → останов. Первые шесть элементов: [1, 2, 3, 5, 7, 8] — отсортированы.
Шаг 6 (элемент с индексом 6, значение 6) Сравниваем с 8: 6 < 8 → меняем → [1, 2, 3, 5, 7, 6, 8, 4] Сравниваем с 7: 6 < 7 → меняем → [1, 2, 3, 5, 6, 7, 8, 4] Сравниваем с 5: 6 > 5 → останов. Первые семь элементов: [1, 2, 3, 5, 6, 7, 8] — отсортированы.
Шаг 7 (элемент с индексом 7, значение 4) Сравниваем с 8: 4 < 8 → меняем → [1, 2, 3, 5, 6, 7, 4, 8] Сравниваем с 7: 4 < 7 → меняем → [1, 2, 3, 5, 6, 4, 7, 8] Сравниваем с 6: 4 < 6 → меняем → [1, 2, 3, 5, 4, 6, 7, 8] Сравниваем с 5: 4 < 5 → меняем → [1, 2, 3, 4, 5, 6, 7, 8] Сравниваем с 3: 4 > 3 → останов. Массив полностью отсортирован: [1, 2, 3, 4, 5, 6, 7, 8]
Сортировка слиянием:
Рассмотрим работу алгоритма сортировки слиянием на массиве [8, 3, 5, 1, 7, 2, 6, 4]:
Шаг 1 (деление на две половины)
Делим массив пополам (по индексу середины):
Левая половина: [8, 3, 5, 1]
Правая половина: [7, 2, 6, 4]
Шаг 2 (рекурсивное деление левой половины [8, 3, 5, 1])
Делим [8, 3, 5, 1] на две части [8, 3] и [5, 1]
Делим [8, 3] на [8] и [3] Делим [5, 1] на [5] и [1]
Теперь левая половина полностью разбита на одноэлементные массивы: [8], [3], [5], [1]
Шаг 3 (рекурсивное деление правой половины [7, 2, 6, 4]
Делим [7, 2, 6, 4] на две части [7, 2] и [6, 4]
Делим [7, 2] на [7] и [2] Делим [6, 4] на [6] и [4]
Правая половина разбита на: [7], [2], [6], [4]
Шаг 4 (слияние (сборка) — начинаем с самых маленьких подмассивов)
Этап 4.1. Слияние пар внутри левой половины
Сливаем [8] и [3]: сравниваем 8 и 3, меньший 3 → результат [3, 8]
Сливаем [5] и [1]: сравниваем 5 и 1 → [1, 5]
После этого левая половина превращается в два отсортированных подмассива: [3, 8] и [1, 5]
Этап 4.2. Слияние пар внутри правой половины
Сливаем [7] и [2] → [2, 7]
Сливаем [6] и [4] → [4, 6]
Правая половина: [2, 7] и [4, 6]
Шаг 5. Слияние полученных подмассивов в половины
5.1. Слияние левых подмассивов [3, 8] и [1, 5]
Сравниваем первые элементы: 1 (из второго) и 3 (из первого). 1 < 3, берём 1 → результат [1], остаются [3,8] и [5]
Сравниваем 3 и 5: 3 < 5, берём 3 → [1,3], остаются [8] и [5]
Сравниваем 5 и 8: 5 < 8, берём 5 → [1,3,5], остаётся [8] → добавляем 8 → [1,3,5,8]
Левая половина после слияния: [1, 3, 5, 8]
5.2. Слияние правых подмассивов [2, 7] и [4, 6]
Сравниваем 2 и 4: 2 < 4 → [2], остаются [7] и [4,6]
Сравниваем 4 и 7: 4 < 7 → [2,4], остаются [7] и [6]
Сравниваем 6 и 7: 6 < 7 → [2,4,6], остаётся [7] → [2,4,6,7]
Правая половина: [2, 4, 6, 7]
Шаг 7. Финальное слияние двух половин
Сливаем [1, 3, 5, 8] и [2, 4, 6, 7]:
Сравниваем 1 и 2 → 1 < 2, берём 1 → результат [1] Остаются: [3,5,8] и [2,4,6,7]
Сравниваем 3 и 2 → 2 < 3, берём 2 → [1,2] Остаются: [3,5,8] и [4,6,7]
Сравниваем 3 и 4 → 3 < 4, берём 3 → [1,2,3] Остаются: [5,8] и [4,6,7]
Сравниваем 5 и 4 → 4 < 5, берём 4 → [1,2,3,4] Остаются: [5,8] и [6,7]
Сравниваем 5 и 6 → 5 < 6, берём 5 → [1,2,3,4,5] Остаются: [8] и [6,7]
Сравниваем 8 и 6 → 6 < 8, берём 6 → [1,2,3,4,5,6] Остаются: [8] и [7]
Сравниваем 8 и 7 → 7 < 8, берём 7 → [1,2,3,4,5,6,7] Остаётся [8] → добавляем → [1,2,3,4,5,6,7,8]
Сравнение алгоритмов
Для сравнения алгоритмов сортировки вставками и слиянием был проведён ряд прогонов программы для различного количества элементов в массиве. На рисунке 1 представлена зависимость времени выполнения алгоритмов от количества элементов в массиве.
Рисунок 1 – График зависимости времени выполнения алгоритмов от количества элементов в массиве
Из графика видно, что сортировка слиянием
работает значительно быстрее, особенно
при увеличении объёма данных. Сортировка
вставками демонстрирует резкий рост
времени выполнения с ростом размера
массива, что объясняется её квадратичной
сложностью
.
Это делает её малоэффективной для
больших массивов по сравнению с
сортировкой слиянием, имеющей сложность
.
Рассмотрим каждый алгоритм подробнее.
Алгоритм сортировки вставками имеет квадратичный рост времени, характерный для сложности . Как видно из графика 1, на небольших массивах алгоритм сортировки вставками работает достаточно быстро, но при увеличении размера массива время выполнения возрастает лавинообразно. Это ограничивает её применение только случаями с малым объёмом данных или частично упорядоченными массивами.
Рассмотрим график сортировки слиянием отдельно:
Рисунок 2 – График зависимости времени выполнения алгоритма сортировки вставками от количества элементов в массиве
Рисунок 2 демонстрирует эффективность сортировки слиянием: время выполнения растёт пропорционально , что подтверждается пологим характером кривой даже при значительном увеличении размера массива. Алгоритм стабильно показывает высокую производительность на всех тестируемых объёмах данных, что делает его предпочтительным выбором для задач, требующих гарантированно быстрой сортировки.
После анализа работы алгоритмов можно сделать следующие выводы:
Сортировка вставками имеет теоретическую и практическую сложность в среднем и худшем случаях. Это подтверждается экспериментальными данными: при увеличении размера массива время выполнения растёт квадратично. Алгоритм прост в реализации и эффективен только для очень маленьких массивов или почти отсортированных данных.
Сортировка слиянием гарантирует сложность во всех случаях, что делает её значительно более производительной на больших объёмах данных. Эксперимент подтверждает теоретические ожидания: даже при максимальном размере массива время остаётся приемлемым, а рост замедляется благодаря логарифмическому множителю. Это позволяет рекомендовать сортировку слиянием для обработки крупных массивов, где важна предсказуемая производительность.
Выводы
В ходе выполнения лабораторной работы были достигнуты следующие результаты:
Изучены два алгоритма сортировки: сортировка вставками и сортировка слиянием. Рассмотрены их теоретические характеристики, включая временную сложность в лучшем, среднем и худшем случаях.
Разработана программа на языке C++, реализующая оба алгоритма и позволяющая измерять время их выполнения. Программа выполняет многократные запуски алгоритмов для усреднения результатов и учитывает затраты на копирование данных, что обеспечивает достоверность полученных значений.
Экспериментально получены зависимости времени выполнения от размера массива, построены соответствующие графики. Анализ графиков подтвердил теоретические оценки сложности: сортировка вставками демонстрирует квадратичный рост времени O(n2), тогда как сортировка слиянием сохраняет эффективность благодаря сложности O(n log n) во всех случаях.
На основе проведённого анализа можно заключить, что сортировка слиянием является предпочтительным выбором для обработки больших объёмов данных, где важна гарантированная скорость сортировки. Сортировка вставками эффективна лишь на малых массивах или при работе с частично упорядоченными данными.
Таким образом, цель работы достигнута: алгоритмы реализованы, их характеристики исследованы, а полученные результаты сопоставлены с теорией.
