← Назад к вопросам

Как устроена функция sort?

2.0 Middle🔥 171 комментариев
#STL контейнеры и алгоритмы

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как устроена функция sort?

Общий механизм

std::sort — это функция из стандартной библиотеки C++ (заголовок <algorithm>), предназначенная для сортировки контейнеров. Она работает с итераторами и использует гибридный алгоритм, который автоматически выбирает оптимальный подход в зависимости от данных.

Гибридный алгоритм сортировки

Модернная реализация std::sort использует IntroSort (интроспективная сортировка) — комбинацию трёх алгоритмов:

  1. QuickSort — основной алгоритм (в среднем O(n log n))
  2. HeapSort — подстраховка при деградации (O(n log n) в худшем случае)
  3. InsertionSort — для маленьких подмассивов (быстрее на малых объёмах)

Как это работает

#include <algorithm>
#include <vector>

int main() {
    std::vector<int> arr = {5, 2, 8, 1, 9};
    
    // Базовая сортировка
    std::sort(arr.begin(), arr.end());
    // Результат: {1, 2, 5, 8, 9}
    
    // С кастомным компаратором
    std::sort(arr.begin(), arr.end(), 
        [](int a, int b) { return a > b; });
    // Результат: {9, 8, 5, 2, 1} — по убыванию
}

Фазы работы IntroSort

Фаза 1 — QuickSort с контролем глубины:

  • Выбирается опорный элемент (pivot)
  • Массив разделяется на две части
  • Рекурсивно сортируются подмассивы
  • Отслеживается глубина рекурсии

Фаза 2 — Переключение на HeapSort:

  • Если глубина превышает 2 * log(n), массив считается "плохим"
  • Код переключается на HeapSort для гарантии O(n log n)
  • Это защита от QuickSort-worst-case (отсортированные данные с плохим pivot)

Фаза 3 — InsertionSort для финиша:

  • Когда размер подмассива < 16 элементов, используется InsertionSort
  • На маленьких данных вставки работают быстрее из-за низких накладных расходов

Сложность

СлучайВремя
СреднийO(n log n)
ЛучшийO(n log n)
ХудшийO(n log n) — благодаря HeapSort
ПамятьO(log n) — на стеке рекурсии

Особенности и оптимизации

Стабильность: std::sort не стабильна — равные элементы могут поменять порядок. Для стабильной сортировки используйте std::stable_sort.

Параллелизм: В некоторых компиляторах (GCC с -D_GLIBCXX_PARALLEL) можно включить параллельную сортировку для больших массивов.

// Сравнение алгоритмов
std::sort(v.begin(), v.end());          // не стабильна
std::stable_sort(v.begin(), v.end());   // стабильна, O(n log n)
std::partial_sort(v.begin(), v.begin()+k, v.end()); // топ-k элементов

Практические советы

  • Выбирайте подходящий компаратор — неправильный компаратор может сломать алгоритм
  • Для стабильности используйте stable_sort
  • Для топ-k используйте partial_sort (быстрее O(n log k))
  • Проверяйте производительность — реальные данные часто отличаются от worst-case

std::sort — это результат десятилетий оптимизации и является одной из самых быстрых реализаций сортировки для общего случая.