Какие алгоритмы используют популярные компиляторы С++ для std:: sort и std:: stable_sort?

Какие алгоритмы используют популярные компиляторы С++ для std:: sort и std:: stable_sort? Я знаю, что стандарт дает только определенные требования к производительности, но я хотел бы знать, какие алгоритмы используются в популярных реализациях на практике.

Ответ был бы более полезным, если бы он ссылался на ссылки для каждой реализации.

Ответ 1

Прежде всего: компиляторы не предоставляют никакой реализации std::sort. Хотя традиционно каждый компилятор поставляется в комплекте с реализацией стандартной библиотеки (которая в значительной степени зависит от встроенных компиляторов), теоретически вы можете поменять одну реализацию на другую. Один очень хороший пример - Clang компилирует libstdc++ (традиционно упакованный с gcc) и libc++ (совершенно новый).

Теперь, когда это не так...

std::sort традиционно был реализован как интро-сортировка. С точки зрения высокого уровня это означает относительно стандартную реализацию быстрой сортировки (с некоторым медианным зондированием, чтобы избежать наихудшего случая O (n 2)) в сочетании с процедурой сортировки вставкой для небольших входных данных. Однако реализация libc++ немного отличается и ближе к TimSort: она обнаруживает уже отсортированные последовательности во входах и избегает их повторной сортировки, что приводит к поведению O (n) на полностью отсортированном входе. Он также использует оптимизированные сети сортировки для небольших входов.

std::stable_sort другой стороны, std::stable_sort более сложный характер. Это можно экстраполировать из самой формулировки Стандарта: сложность составляет O (n log n), если может быть выделено достаточно дополнительной памяти (намекает на сортировку слиянием), но вырождается в O (n log 2 n), если нет.

Ответ 2

Если мы возьмем gcc в качестве примера, мы увидим, что он introsort для std::sort и mergesort для std::stable_sort.

Если вы пробираетесь через код libС++, вы увидите, что он также использует mergesort для std::stable_sort, если диапазон достаточно велик.

Следует отметить также, что, хотя общий подход всегда является одним из вышеупомянутых, все они очень оптимизированы для различных особых случаев.