Quelle est la complexité de std::sort()
dans la bibliothèque standard C++? Quel genre est appliqué? Existe-t-il une règle d'application d'un algorithme de tri particulier?
std::sort
doit avoir une complexité temporelle linéaire (n log n) à la casse moyenne. Tout algorithme peut être utilisé tant que cette exigence de complexité temporelle est satisfaite. Il n'y a pas de pire cas de complexité temporelle.
Si vous voulez une fonction de complexité temporelle garantie dans le pire des cas, utilisez std::stable_sort
, qui présente une complexité temporelle dans le pire cas quasi linéaire (n log ^ 2 n).
http://en.wikipedia.org/wiki/Sort_(C%2B%2B)
L'algorithme de tri spécifique n'est pas obligatoire et peut varier d'une implémentation à l'autre. La bibliothèque GNU Standard C++, par exemple, utilise un algorithme de tri hybride: l’introsort est exécuté en premier, à une profondeur maximale donnée par 2 × log2 n, où n est le nombre résultat. [1] Quelle que soit la mise en œuvre, la complexité devrait être O (n log n) des comparaisons en moyenne. [2]
La complexité est O(n log n)
. Certaines implémentations courantes utilisent introsort pour autant que je sache:
À partir de la norme C++ 11/14, std::sort
est garanti pour avoir:
§25.4.1.1/3
Complexité:
O(N log(N))
(oùN == last - first
) comparaisons.
L’autre algorithme de tri standard stable (à savoir std::stable_sort
) est garanti pour avoir:
25.4.1.2/3
Complexité: Il effectue au maximum
N log2(N)
(oùN == last - first
) des comparaisons; Si suffisamment de mémoire supplémentaire est disponible, il s’agit deN log(N)
.
Pour std::forward_list::stable
, à la place:
23.3.4.6/26
Complexité: Comparaisons approximatives de
N log(N)
, oùN
estdistance(begin(), end())
.
Il en va de même pour std::list
:
23.3.5.5/31
Complexité: Comparaisons approximatives de
N log(N)
, oùN == size()
.
La norme C++ ne spécifie pas l'algorithme de tri à appliquer dans les cas ci-dessus. Ce serait souvent une restriction inutile de la mise en œuvre.
Si vous avez besoin de savoir, vous aurez peut-être de la chance dans une spécification spécifique du compilateur. Par exemple, pour GNU GCC, vous démarrez ici .
Si vous voulez dire std::sort()
:
Cela provient du standard C++ 03, section 25.3. La garantie de performance:
template<class RandomAccessIterator>
void sort(RandomAccessIterator first, RandomAccessIterator last);
template<class RandomAccessIterator, class Compare> void sort(RandomAccessIterator first, RandomAccessIterator last,
Compare comp);
1 Effets: Trie les éléments de la plage [premier, dernier).
2 Complexité: environ N log N (où N == dernier - premier) comparaisons en moyenne.
La norme C++ spécifie que le scénario d'exécution le plus défavorable de std::sort()
est dans O(n log n)
- où n
est le nombre d'éléments triés (voir C++ 11, Section 25.4.1.1).
La norme ne spécifie pas un algorithme de tri particulier.
Ainsi, une implémentation std::sort()
conforme est libre de choisir n’importe quel algorithme répondant aux exigences d’exécution ci-dessus.
Notez que les révisions standard C++ antérieures à C++ 11 exigent simplement que le runtime average de std::sort()
soit dans O(n log n)
.
Voir aussi la question de stackoverflow Quels algorithmes sont utilisés dans C++ 11 std :: sort dans différentes implémentations STL? pour avoir une idée des algorithmes de tri utilisés dans les implémentations STL du monde réel.