Сортировки
Сортировка - алгоритм упорядочивания элементов в списке - достаточно распространенная задача программирования. Существуют многочисленные алгоритмы сортировки - простые и сложные - о них мы поговорим далее.
В данной статье мы рассмотрим следующие темы:
- Сортировка пузырьком
- Сортировка вставками
- Сортировка слиянием
- Быстрая сортировка
- Стандартный алгоритм сортировки
- Компараторы
- Стабильная сортировка
Сортировка пузырьком
Сортировка пузырьком (Bubble sort) проста в реализации, однако сложность данного алгоритма оставляет желать лучшего - \(O(n^2)\). Поэтому, на практике данный алгоритм применяется редко, лишь в качестве обучения.
Чтобы понять, как работает данный алгоритм, предлагаю ознакомиться со следующим видеороликом:
Сортировка вставками
Сортировка вставками (Insertion sort), вычислительная сложность - \(O(n^2)\).
Сортировка слиянием
Сортировка слиянием (Merge sort). Вычислительная сложность - \(O(n\log(n))\). Реализуем рекурсивный способ данной сортировки. С этой целью, спроектируем две процедуры - sort и merge. Процедура merge будет отвечать за объединение массивов в единный массив
Процедура sort отвечает непосредственно рекурсивную сортировку.
Осталось лишь в главной функции вызвать процедуру sort:
Важное замечание: в функции main() мы нумеровали массив А начиная с 1.
Быстрая сортировка
Быстрая сортировка (quick sort), известная также как сортировка Хоара, - один из самых быстрых универальных алгоритмов сортировки, вычислительная сложность - \(O(n\log(n))\). Стоит заметить, что это средняя сложность. В худшем случае сложность будет \(On^2\)
Стандартный алгоритм сортировки
Чтобы каждый раз не реализовывать в своем проекте алгоритм сортировки, разработчики добавили в язык встроенный алгоритм сортировки. Для того, чтобы его использовать, нужно подключить библиотеку algorithm. Итак, в общем виде стандартный алгоритм сортировки выглядит так:
Где arr(имя массива) является первым аргументом (началом диапазона сортировки), a n - количество элементов в массиве (то есть arr + n - это конец диапазона сортировки). Также при необходимости мы можем использовать третий аргумент - компаратор - о нем мы поговорим далее. Если мы захотим отсортировать vector, мы будем использовать такие аргументы:
Компараторы
Иногда в задаче требуется отсортировать не числа, а некоторые сложные объекты, состоящие из нескольких элементов. Для сортировки таких объектов чаще всего нужно вручную указывать параметр, который будет сравниваться при сортировке. Для этого и предназначены компараторы.
Компаратор в C++ - логическая функция, которая принимает два объекта одинакового типа, и возвращает true, если первый из них “меньше” второго и false в противном случае. В этом контексте “меньше” значит, что в отсортированном массиве этот элемент обязательно должен стоять раньше.
Рассмотрим постой пример: нам нужно купить автомобиль. Введем в рассмотрение такую величину как оценку комфорта по десятибалльной шкале. Первое, на что мы должны ориентироваться, это комфорт, а далее уже цена.
Для этого нам понадобится разработать структуру car:
Далее напишем сам комраратор:
Теперь мы можем использовать компаратор как третий аргумент функции sort. Полный код решения:
Стабильная сортировка
Рассмотрим следующий массив структур:
Как должен быть отсортирован данный массив? Возможны два варианта:
или
При стандартной сортировке возможны оба этих случая, тогда как при стабильной сортировке возможен только первый, так как относительное положение “Mersedes” и “Hyundai” сохраняется. Стандартная библиотека C++ включает в себя оптимальную реализацию алгоритма стабильной сортировки со сложностью \(O(n\log n)\). Как и в std::sort, определены две перегрузки:
Разумеется, за стабильность приходится платить другими характеристиками. Стабильная сортировка работает медленнее, чем нестабильная, хотя их сложность одинаковая: \(O(n\log n)\).