Die vorherigen Antworten befassen sich nur mit Baumalternativen und Rot-Schwarz bleibt wahrscheinlich nur aus historischen Gründen.
Warum nicht eine Hash-Tabelle?
Für einen Typ muss nur der <
Operator (Vergleich) als Schlüssel in einem Baum verwendet werden. Für Hash-Tabellen muss jedoch für jeden Schlüsseltyp eine hash
Funktion definiert sein. Für eine generische Programmierung ist es sehr wichtig, die Typanforderungen auf ein Minimum zu beschränken, damit Sie sie mit einer Vielzahl von Typen und Algorithmen verwenden können.
Das Entwerfen einer guten Hash-Tabelle erfordert genaue Kenntnisse des Kontexts, in dem sie verwendet wird. Sollte es offene Adressierung oder verknüpfte Verkettung verwenden? Welche Belastungsstufen sollte es vor dem Ändern der Größe akzeptieren? Sollte es einen teuren Hash verwenden, der Kollisionen vermeidet, oder einen, der rau und schnell ist?
Da die STL nicht vorhersehen kann, welche die beste Wahl für Ihre Anwendung ist, muss die Standardeinstellung flexibler sein. Bäume "funktionieren einfach" und skalieren gut.
(C ++ 11 hat Hash-Tabellen mit hinzugefügt unordered_map
. Sie können der Dokumentation entnehmen , dass Richtlinien festgelegt werden müssen, um viele dieser Optionen zu konfigurieren.)
Was ist mit anderen Bäumen?
Rot-Schwarz-Bäume bieten eine schnelle Suche und sind im Gegensatz zu BSTs selbstausgleichend. Ein anderer Benutzer wies auf seine Vorteile gegenüber dem selbstausgleichenden AVL-Baum hin.
Alexander Stepanov (der Schöpfer von STL) sagte, dass er einen B * -Baum anstelle eines Rot-Schwarz-Baums verwenden würde, wenn er std::map
erneut schreiben würde, da dies für moderne Speicher-Caches freundlicher ist.
Eine der größten Änderungen seitdem war das Wachstum von Caches. Cache-Fehler sind sehr kostspielig, daher ist die Referenzlokalität jetzt viel wichtiger. Knotenbasierte Datenstrukturen mit geringer Referenzlokalität sind viel weniger sinnvoll. Wenn ich heute STL entwerfen würde, hätte ich einen anderen Satz von Containern. Beispielsweise ist ein speicherinterner B * -Baum eine weitaus bessere Wahl als ein rot-schwarzer Baum für die Implementierung eines assoziativen Containers. - Alexander Stepanov
Sollten Karten immer Bäume verwenden?
Eine andere mögliche Kartenimplementierung wäre ein sortierter Vektor (Einfügungssortierung) und eine binäre Suche. Dies funktioniert gut für Container, die nicht häufig geändert, aber häufig abgefragt werden. Ich mache das oft in C as qsort
und bin bsearch
eingebaut.
Muss ich überhaupt eine Karte verwenden?
Cache Überlegungen bedeuten , es selten sinnvoll Gebrauch macht std::list
oder std::deque
über std:vector
selbst für jene Situationen , die wir in der Schule gelernt hatten (wie zum Beispiel ein Element aus der Mitte der Liste zu entfernen). Wenn Sie dieselbe Argumentation anwenden, ist die Verwendung einer for-Schleife für die lineare Suche in einer Liste häufig effizienter und sauberer als die Erstellung einer Karte für einige Suchvorgänge.
Natürlich ist die Auswahl eines lesbaren Containers normalerweise wichtiger als die Leistung.