Ici http://www.cplusplus.com/reference/stl/set/ J'ai lu que std :: set en C++ est "typiquement" implémenté comme un arbre (un rouge-noir?) Et il est trié.
Je ne pouvais pas comprendre, cela signifie-t-il que par spécification l'ordre d'itération de l'ensemble est toujours croissant? Ou s'agit-il uniquement de "détails d'implémentation habituels" et parfois, certaines bibliothèques/compilateurs peuvent violer cette convention?
Selon la norme C++, itération sur les éléments dans un std::set
procède dans un ordre trié déterminé par std::less
ou par l'argument de modèle de prédicat de comparaison facultatif.
(Toujours selon la norme C++, l'insertion, la recherche et la suppression prennent au maximum O (lg n) temps, donc les arbres de recherche équilibrés sont actuellement le seul choix d'implémentation viable pour std::set
, même si l'utilisation d'arbres rouge-noir n'est pas imposée par la norme.)
Cela signifie qu'en interne std::set
stockera ses éléments sous forme d'arbre trié. Cependant, la spécification ne dit rien sur l'ordre de tri. Par défaut, std::set
les usages std::less
et ainsi passera de bas en haut. Cependant, vous pouvez faire en sorte que la fonction de tri soit celle que vous voulez, en utilisant ce paramètre de modèle:
std::set<valueType, comparissonStruct> myCustomOrderedSet;
Ainsi, par exemple:
std::set<int, std::greater<int> > myInverseSortedSet;
ou
struct cmpStruct {
bool operator() (int const & lhs, int const & rhs) const
{
return lhs > rhs;
}
};
std::set<int, cmpStruct > myInverseSortedSet;
En fait, ces exemples sont également fournis sur le site Web que vous avez lié. Plus précisément ici: set constructor .
Le comparateur par défaut est inférieur, donc l'ensemble sera ordonné croissant. Pour changer cela, vous pouvez spécifier un autre comparateur existant ou personnalisé comme argument de modèle.
Projet standard C++ 11 N3337
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
23.2.4 "Conteneurs associatifs" dit:
1 Les conteneurs associatifs permettent une récupération rapide des données en fonction des clés. La bibliothèque propose quatre types de base de conteneurs associatifs: set, multiset, map et multimap.
et:
10 La propriété fondamentale des itérateurs de conteneurs associatifs est qu'ils parcourent les conteneurs dans l'ordre non décroissant des clés où non descendant est défini par la comparaison qui a été utilisée pour les construire.
donc oui , l'ordre est garanti par le standard C++.
C'est pourquoi gcc 6.4.0 l'implémente par exemple en tant que BST au lieu de hashmap: Quelle est la structure de données sous-jacente d'un ensemble STL en C++?
Comparez cela avec C++ 11 unordered_set
, ce qui tend à fournir de meilleures performances avec une implémentation de hashmap, au prix d'être plus restreint (pas de traversée triée libre) comme indiqué à:
par spécification, l'ordre d'itération de l'ensemble est toujours croissant
Oui, les valeurs de set sont toujours croissantes si vous les imprimez en séquence. Comme le dit la description, il est généralement implémenté à l'aide de Red-Black Tree (RBT), mais les rédacteurs du compilateur ont la possibilité de violer cela, mais généralement ils s'en tiendraient au thème de RBT car toute autre implémentation ne sera pas efficace en termes de ressources pour atteindre la tâche de set
.