Überall, wo ich hinschaue, werden Datenstrukturen mithilfe von rot-schwarzen Bäumen implementiert ( std::set
in C ++, SortedDictionary
in C # usw.).
Nachdem ich gerade (a, b), Rot-Schwarz- und AVL-Bäume in meinem Algorithmus-Kurs behandelt habe, habe ich Folgendes herausgefunden (auch nachdem ich mich bei Professoren erkundigt, ein paar Bücher durchgesehen und ein bisschen gegoogelt habe):
- AVL-Bäume haben eine geringere durchschnittliche Tiefe als rot-schwarze Bäume, und daher ist die Suche nach einem Wert im AVL-Baum durchgehend schneller.
- Rot-schwarze Bäume führen weniger strukturelle Änderungen durch, um sich auszugleichen als AVL-Bäume, wodurch sie möglicherweise schneller zum Einfügen / Löschen verwendet werden können. Ich sage möglicherweise, weil dies von den Kosten der strukturellen Änderung des Baums abhängen würde, da dies sehr stark von der Laufzeit und der Implementierung abhängen wird (könnte in einer funktionalen Sprache auch völlig anders sein, wenn der Baum unveränderlich ist?)
Es gibt viele Online-Benchmarks, die AVL- und Rot-Schwarz-Bäume vergleichen. Was mich jedoch beeindruckt hat, ist, dass mein Professor im Grunde gesagt hat, dass Sie normalerweise eines von zwei Dingen tun würden:
- Entweder interessiert Sie die Leistung nicht so sehr. In diesem Fall spielt der Unterschied zwischen AVL und Rot-Schwarz in den meisten Fällen keine Rolle.
- Oder Sie legen großen Wert auf Leistung. In diesem Fall würden Sie sowohl AVL- als auch Rot-Schwarz-Bäume wegwerfen und sich für B-Bäume entscheiden, die optimiert werden können, um besser zu funktionieren (oder (a, b) -Bäume, I '). Ich werde alle in einen Korb legen.)
Der Grund dafür ist, dass ein B-Baum Daten kompakter im Speicher speichert (ein Knoten enthält viele Werte), und es wird viel weniger Cache-Fehlschläge geben. Sie können die Implementierung auch basierend auf dem Anwendungsfall optimieren und die Reihenfolge des B-Baums von der CPU-Cache-Größe usw. abhängig machen.
Das Problem ist, dass ich kaum eine Quelle finden kann, die die tatsächliche Verwendung verschiedener Implementierungen von Suchbäumen auf moderner Hardware analysiert. Ich habe viele Bücher über Algorithmen durchgesehen und nichts gefunden, das verschiedene Baumvarianten miteinander vergleichen könnte, außer zu zeigen, dass einer eine geringere durchschnittliche Tiefe hat als der andere (was nicht wirklich aussagt, wie sich der Baum verhält) in echten Programmen.)
Abgesehen davon, gibt es einen besonderen Grund, warum überall rot-schwarze Bäume verwendet werden, wenn auf der Grundlage der obigen Aussagen B-Bäume diese übertreffen sollten? (Als einziger Benchmark konnte ich auch http://lh3lh3.users.sourceforge.net/udb.shtml finden , aber es könnte nur eine Frage der spezifischen Implementierung sein). Oder ist es der Grund, warum jeder rot-schwarze Bäume verwendet, weil sie ziemlich einfach zu implementieren oder anders ausgedrückt, schwer zu implementieren sind?
Wie ändert sich dies auch, wenn man in den Bereich der funktionalen Sprachen wechselt? Es scheint, dass sowohl Clojure als auch Scala Hash-Array-zugeordnete Versuche verwenden , wobei Clojure einen Verzweigungsfaktor von 32 verwendet.