Warum ist std :: map als rot-schwarz Baum umgesetzt?

stimmen
130

Warum ist std :: map als implementiert rot-schwarz - Baum ?

Es gibt mehrere ausgeglichene binäre Suchbäume (BSTs) da draußen. Was waren Design Trade-offs in einen rot-schwarz - Baum auswählen?

Veröffentlicht am 13/03/2011 um 09:33
quelle vom benutzer
In anderen Sprachen...                            


6 antworten

stimmen
86

Wahrscheinlich sind die beiden häufigsten Baum Selbstausgleichsalgorithmen sind Rot-Schwarz Bäume und AVL - Bäume . Zum Ausgleich des Baumes nach einem Update Einfügen / beide Algorithmen , um die Vorstellung von Rotationen verwenden , in denen die Knoten des Baumes gedreht werden , um die Neugewichtung durchzuführen.

Während sowohl die Insert - Algorithmen / Löschoperationen sind O (log n), im Falle von Rot-Schwarz - Baum Neugewichtung Rotation ist ein O (1) Betrieb während mit AVL dies ist ein O (n log) Betrieb, so dass die rot-Schwarz - Baum effizienter in diesem Aspekt der Neugewichtung Stufe und einer der möglichen Gründe dafür , dass es häufiger verwendet wird.

Rot-Schwarz Bäume sind in den meisten Sammlung Bibliotheken, darunter die Angebote von Java und Microsoft .NET Framework verwendet.

Beantwortet am 13/03/2011 um 09:47
quelle vom benutzer

stimmen
2

Es ist nur die Wahl Ihrer Umsetzung - sie als eine funktionierende Baum umgesetzt werden könnten. Die verschiedenen Möglichkeiten sind vergleichbar mit kleinen Unterschieden. Deshalb ist jeder so gut wie jeder andere.

Beantwortet am 13/03/2011 um 09:48
quelle vom benutzer

stimmen
22

AVL-Bäume haben eine maximale Höhe von 1.44logn, während RB Bäume maximal 2logn haben. ein Element in einem AVL Einsetzen kann eine Neuverteilung bei einem Punkt in der Baumstruktur impliziert. Die rebalancing beendet die Insertion. Nach dem Einsetzen eines neuen Blatt hat die Vorfahren des Blattes Aktualisierung an die Wurzel getan werden, oder bis zu einem Punkt, wo die beiden Unterstrukturen von gleicher Tiefe sind. Die Wahrscheinlichkeit von Knoten k zu aktualisieren ist, die 1/3 ^ k. Rebalancing ist O (1). Entfernen ein Elements kann mehr als einen ausgleich implizieren (bis zur Hälfte der Tiefe des Baumes).

RB-Bäume sind B-Bäume der Ordnung 4 als binäre Suchbäume dargestellt. Ein 4-Knoten in den B-Baum-Ergebnissen in zwei Ebenen in der äquivalenten BST. Im schlimmsten Fall sind alle Knoten des Baums sind 2-Knoten, mit nur einer Kette von 3-Knoten bis zu einem Blatt. Das Blatt wird von der Wurzel in einem Abstand von 2logn sein.

Ablaufend von der Wurzel bis zur Einfügemarke, hat ein 4-Knoten in 2-Knoten zu ändern, jede Einfügung, um sicherzustellen, wird ein Blatt nicht sättigen. Kommen wir zurück von der Insertion, all diese Knoten müssen analysiert werden, um sicherzustellen, dass sie richtig 4-Knoten repräsentieren. Dies kann auch hinunter in den Baum durchgeführt werden. Die Gesamtkosten werden die gleichen sein. Es gibt kein freies Mittagessen! ein Element aus dem Baum zu entfernen, ist in der gleichen Größenordnung.

Alle diese Bäume erfordern, dass die Knoten tragen Informationen über Größe, Gewicht, Farbe, etc. Nur Splay Bäume sind frei von solchen zusätzlichen Informationen. Aber die meisten Menschen haben Angst vor Splay Bäume wegen der ramdomness ihrer Struktur!

Schließlich Bäume können auch Gewichtsinformationen in den Knoten führen, Gewichtsausgleich ermöglicht. Verschiedene Schemata können angewendet werden. Man sollte Neuverteilung wenn ein Teilbaum mehr als 3 mal die Anzahl der Elemente des anderen Teilbaum enthält. Rebalancing wird wieder entweder throuh Einzel- oder Doppeldrehung erfolgt. Das bedeutet, eine Worst-Case von 2.4logn. Man kann mit 2 mal weg statt 3, ein viel besseres Verhältnis, aber es kann bedeuten, etwas weniger thant 1% der Teilbäume verlassen unausgewogen hier und da. Tricky!

Welche Art von Baum ist die beste? AVL sicher. Sie sind am einfachsten zu Code und haben ihre schlimmste Höhe am nächsten logn. Für einen Baum von Elementen 1000000 wird eine AVL höchstens der Höhe beträgt 29, eine RB 40 und ein Gewicht 36 oder 50 je nach dem Verhältnis ausgewogen.

Es gibt eine Menge von anderen Variablen: Zufälligkeit, das Verhältnis der hinzufügt, löscht, Durchsuchung, usw.

Beantwortet am 16/07/2011 um 02:52
quelle vom benutzer

stimmen
36

Es hängt wirklich von der Nutzung. AVL-Baum hat in der Regel mehr Drehungen Rebalancing. Also, wenn Ihre Anwendung nicht über zu viele Einfügen und Löschen-Operationen, aber Gewichte stark auf Suche, dann wahrscheinlich AVL-Baum ist eine gute Wahl.

std::map verwendet Rot-Schwarz-Baum, wie es einen vernünftigen Kompromiss zwischen der Geschwindigkeit der Knoten Einfügen / Löschen und der Suche wird.

Beantwortet am 26/05/2012 um 19:32
quelle vom benutzer

stimmen
2

Aktualisieren 2017.06.14: webbertiger bearbeiten ihre Antwort, nachdem ich kommentiert. Ich sollte darauf hinweisen, dass die Antwort ist jetzt viel besser in meinen Augen. Aber ich behielt meine Antwort nur als zusätzliche Informationen ...

Aufgrund der Tatsache, dass ich denke, erste Antwort falsch ist (Korrektur: nicht beide mehr) und der dritte eine falsche Behauptung hat. Ich glaube, ich hatte Dinge zu klären ...

Der 2 beliebtestene Baum ist AVL und Rot Schwarz (RB). Der Hauptunterschied liegt in der Verwendung:

  • AVL: Besser, wenn Verhältnis von Beratung (lesen) ist größer als Manipulation (Modifikation). Speicherplatzbedarf ist ein wenig kleiner als RB (aufgrund der Bit für die Färbung erforderlich).
  • RB: Besser im allgemeinen Fällen, in denen es ein Gleichgewicht zwischen Beratung (Lesen) und Manipulation (Modifikation) oder mehr Modifikation über Beratung. Ein etwas größerer Speicherbedarf aufgrund der Speicherung von rot-schwarz-Flag.

Der Hauptunterschied von der Färbung kommen. Sie haben noch weniger wieder ins Gleichgewicht Aktion in RB Baum als AVL, weil die Färbung Sie manchmal ermöglichen, wieder ins Gleichgewicht Aktion überspringen oder zu verkürzen, die ein relativ hallo Kosten haben. Wegen der Färbung, auch RB Baum höhere Ebene von Knoten haben, weil es rot Knoten zwischen schwarzen annehmen könnte (mit den Möglichkeiten von ~ 2x mehr Ebenen) zu machen suchen (lesen) ein wenig weniger effizient ... aber da es sich um eine konstante (2x), ist es in O (log n) bleiben.

Wenn Sie die Performance-Einbußen für eine Änderung eines Baumes (significative) VS die Leistungseinbußen der Konsultation eines Baumes (fast unbedeutend) betrachten, werden sie natürlich RB über AVL für einen allgemeinen Fall zu bevorzugen.

Beantwortet am 30/05/2017 um 20:33
quelle vom benutzer

stimmen
5

Die bisherigen Antworten Adresse nur Baum Alternativen und rot schwarz bleibt wohl nur aus historischen Gründen.

Warum nicht eine Hash-Tabelle?

In einem Baum erfordert eine Art nur partielle Ordnung (<Vergleich) als Schlüssel in der Karte verwendet werden. Jedoch Hash-Tabellen erfordern, dass jeder Schlüsseltyp eine Hash-Funktion definiert ist. diese Art Anforderungen auf ein Minimum zu halten, ist sehr wichtig für die generische Programmierung.

eine gute Hash-Tabelle Gestaltung erfordert genaue Kenntnis des Kontexts es, die sie verwendet werden sollen. Sollte es offen Adressierung oder verknüpft Verkettungs verwenden? Welche Ebene der Last soll es vor dem Ändern der Größe annehmen? Sollte es eine teure Hash verwenden, die Kollisionen vermeidet, oder eine, die rau und schnell ist?

(C ++ 11 hat mit Hash - Tabellen hinzufügen unordered_map. Sie können von der siehe Dokumentation es erfordert Richtlinien Einstellung viele dieser Optionen zu konfigurieren.)

Da die STL nicht voraussehen kann, welche die beste Wahl für Ihre Anwendung ist, muss der Standard flexibler sein. Bäume „einfach funktionieren“ und skalieren schön.

Was ist mit anderen Bäumen?

Red Black tree Angebot schnelles Nachschlagen und balancieren sich selbst im Gegensatz zu BSTs. Ein anderer Benutzer darauf hingewiesen, ihre Vorteile gegenüber dem Selbst-Balancing AVL-Baum.

Alexander Stepanov (Der Schöpfer des STL) sagte , dass er einen B * -Baum anstelle eines Rot-Schwarz - Baum verwenden würde , wenn er schrieb std::mapwieder. Dies liegt daran , die Knoten eine beliebige Anzahl von Elementen speichern kann zusammenhängend , die freundlicher für moderne Speicher - Caches ist.

Eine der größten Veränderungen seit damals hat sich das Wachstum von Caches gewesen. Cache-Misses sind sehr teuer, so Referenzlokalität ist viel wichtiger, jetzt. Node-basierte Datenstrukturen, die eine niedrige Referenzlokalität haben, machen viel weniger Sinn. Wenn ich STL heute entwarfen, würde ich einen anderen Satz von Containern haben. Zum Beispiel ist ein In-Memory-B * -Baum eine weit bessere Wahl als ein rot-schwarz-Baum für einen assoziativen Container implementieren. - Alexander Stepanov

Sie können mehr lesen hier

Ist Rot-Schwarz-Baum oder B * immer die beste?

Bei anderen Gelegenheiten Alex hat erklärt , dass std::vectorfast immer die beste Liste Container aus ähnlichen Gründen sind. Es macht selten Sinn zu verwenden std::listoder std::dequeauch für jene Situationen , die wir in der Schule (wie das Entfernen eines Elements aus der Mitte der Liste) unterrichtet wurden. std::vectorso schnell ist , dass es diese Strukturen für alles , aber große n schlägt.

Die gleiche Argumentation Anwendung , wenn Sie nur eine kleine Anzahl von Elementen haben (Hunderte?) Eine mit std::vectorund linearen Suche kann effizienter als der Baum Umsetzung sein std::map. Je nach Häufigkeit des Einsetzens, sortierte eine std::vectorKombination mit std::binary_searchkann die schnellste Wahl sein.

Beantwortet am 22/12/2017 um 00:46
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more