Rot-schwarzer Baum

Ein rot-schwarzer Baum ist ein Typ, binären Suchbaum, eine Datenstruktur zu selbsterwägen, die in der Informatik verwendet ist, normalerweise assoziative Reihe durchzuführen. Die ursprüngliche Struktur wurde 1972 von Rudolf Bayer erfunden und "symmetrischen binären B-Baum," genannt, aber hat seinen modernen Namen in einem Vortrag 1978 von Leonidas J. Guibas und Robert Sedgewick erworben.

Da es ein erwogener Baum ist, versichert es Einfügung, suchen Sie und löschen Sie, um O zu sein (loggen Sie n) rechtzeitig, wo n die Gesamtzahl von Elementen im Baum ist.

Ein rot-schwarzer Baum ist ein binärer Suchbaum, der einfügt und auf solche Art und Weise löscht, dass der Baum immer vernünftig erwogen wird.

Fachsprache

Ein rot-schwarzer Baum ist ein spezieller Typ des binären Baums, der in der Informatik verwendet ist, um Stücke von vergleichbaren Daten, wie Textbruchstücke oder Zahlen zu organisieren.

Die Blatt-Knoten von rot-schwarzen Bäumen enthalten Daten nicht. Diese Blätter brauchen im Computergedächtnis nicht ausführlich zu sein — ein ungültiger Kinderzeigestock kann die Tatsache verschlüsseln, dass dieses Kind ein Blatt ist — aber es vereinfacht einige Algorithmen, um auf rot-schwarzen Bäumen zu funktionieren, wenn die Blätter wirklich ausführliche Knoten sind. Um Gedächtnis manchmal zu sparen, führt ein einzelner Wächter-Knoten die Rolle aller Blatt-Knoten durch; alle Verweisungen von inneren Knoten bis Blatt-Knoten weisen dann zum Wächter-Knoten hin.

Rot-schwarze Bäume, wie alle binären Suchbäume, erlauben effizient um Traversal nach der Mode, dem Nach links Wurzelrecht von ihren Elementen. Die Suchzeit ergibt sich aus dem Traversal von der Wurzel bis Blatt, und deshalb einen erwogenen Baum, die am wenigsten mögliche Baumhöhe habend, läuft auf O hinaus (loggen Sie n) Suchzeit.

Eigenschaften

Ein rot-schwarzer Baum ist ein binärer Suchbaum, wo jeder Knoten ein Farbenattribut hat, dessen Wert entweder rot oder schwarz ist. Zusätzlich zu den gewöhnlichen binären Suchbäumen auferlegten Voraussetzungen gelten die folgenden Voraussetzungen für rot-schwarze Bäume:

  1. Ein Knoten ist entweder rot oder schwarz.
  2. Die Wurzel ist schwarz. (Diese Regel wird manchmal aus anderen Definitionen weggelassen. Da die Wurzel immer von rot bis schwarz, aber nicht notwendigerweise umgekehrt geändert werden kann, hat diese Regel wenig Wirkung auf die Analyse.)
  3. Alle Blätter sind dieselbe Farbe wie die Wurzel.
  4. Beide Kinder jedes roten Knotens sind schwarz.
  5. Jeder einfache Pfad von einem gegebenen Knoten bis einige seiner Nachkomme-Blätter enthält dieselbe Zahl von schwarzen Knoten.

Diese Einschränkungen machen ein kritisches Eigentum von rot-schwarzen Bäumen geltend: Dass der Pfad von der Wurzel bis das weiteste Blatt nicht mehr als zweimal so lang ist wie der Pfad von der Wurzel bis das nächste Blatt. Das Ergebnis besteht darin, dass der Baum grob erwogen wird. Seit Operationen wie das Einfügen verlangen das Löschen und die Entdeckung von Werten zur Höhe des Baums proportionale Grenzfall-Zeit, das theoretisch ober hat zur Höhe gebunden erlaubt rot-schwarzen Bäumen, im Grenzfall verschieden von gewöhnlichen binären Suchbäumen effizient zu sein.

Um zu sehen, warum das versichert wird, genügt es, um die Wirkung von Eigenschaften 4 und 5 zusammen zu denken. Für einen rot-schwarzen Baum T, lassen Sie B die Zahl von schwarzen Knoten im Eigentum 5 sein. Deshalb besteht der kürzestmögliche Pfad von der Wurzel von T zu jedem Blatt aus B schwarzen Knoten. Längere mögliche Pfade können durch das Einfügen roter Knoten gebaut werden. Jedoch macht Eigentum 4 es unmöglich, mehr als einen roten Konsekutivknoten einzufügen. Deshalb besteht der längstmögliche Pfad aus 2B Knoten, schwarz und rot abwechselnd.

Der kürzestmögliche Pfad hat alle schwarzen Knoten und die längstmöglichen Pfad-Stellvertreter zwischen roten und schwarzen Knoten. Da alle maximalen Pfade dieselbe Zahl von schwarzen Knoten, durch das Eigentum 5 haben, zeigt das, dass kein Pfad mehr als zweimal so lang ist wie jeder andere Pfad.

In vielen der Präsentationen von Baumdatenstrukturen ist es für einen Knoten möglich, nur ein Kind zu haben, und Blatt-Knoten enthalten Daten. Es ist möglich, rot-schwarze Bäume in diesem Paradigma zu präsentieren, aber es ändert mehrere der Eigenschaften und kompliziert die Algorithmen. Deshalb verwendet dieser Artikel "ungültige Blätter", die keine Daten enthalten und bloß dienen, um anzuzeigen, wo der Baum, wie gezeigt, oben endet. Diese Knoten werden häufig in Zeichnungen weggelassen, auf einen Baum hinauslaufend, der scheint, den obengenannten Grundsätzen zu widersprechen, aber tatsächlich nicht tut. Eine Folge davon ist, dass ganz inner (Nichtblatt) Knoten zwei Kinder haben, obwohl ein oder beide jener Kinder ungültige Blätter sein kann. Eigentum 5 stellt sicher, dass ein roter Knoten entweder zwei schwarze ungültige Blätter oder zwei schwarze Nichtblätter als Kinder haben muss. Für einen schwarzen Knoten mit einem ungültigem Blatt-Kind und einem Kind "stellt nicht ungültiges Blatt", Eigenschaften 3, 4 und 5 sicher, dass das Kind "nicht ungültiges Blatt" ein roter Knoten mit zwei schwarzen ungültigen Blättern als Kinder sein muss.

Einige erklären einen rot-schwarzen Baum als ein binärer Suchbaum, dessen Ränder, statt Knoten, in rot oder Schwarzem gefärbt werden, aber das macht keinen Unterschied. Die Farbe eines Knotens in der Fachsprache dieses Artikels entspricht der Farbe des Randes, der den Knoten mit seinem Elternteil verbindet, außer dass der Wurzelknoten immer schwarz ist (Eigentum 2), wohingegen der entsprechende Rand nicht besteht.

Analogie zu B-Bäumen des Auftrags 4

Ein rot-schwarzer Baum ist in der Struktur einem B-Baum des Auftrags 4 ähnlich, wo jeder Knoten zwischen 1 bis 3 Werten und (entsprechend) zwischen 2 bis 4 Kinderzeigestöcken enthalten kann. In solchem B-Baum wird jeder Knoten nur einen Wert enthalten, der den Wert in einem schwarzen Knoten des rot-schwarzen Baums, mit einem fakultativen Wert vorher und/oder danach in demselben Knoten, das beides Zusammenbringen eines gleichwertigen roten Knotens des rot-schwarzen Baums vergleicht.

Eine Weise, diese Gleichwertigkeit zu sehen, soll die roten Knoten in einer grafischen Darstellung des rot-schwarzen Baums "heranbringen", so dass sie sich horizontal auf ihren schwarzen Elternteilknoten ausrichten, indem sie zusammen eine horizontale Traube schaffen. Im B-Baum, oder in der modifizierten grafischen Darstellung des rot-schwarzen Baums sind alle Blatt-Knoten an derselben Tiefe.

Der rot-schwarze Baum ist dann zu einem B-Baum des Auftrags 4 strukturell gleichwertig, mit einem Minimum füllen Faktor von 33 % von Werten pro Traube mit einer maximalen Kapazität von 3 Werten.

Dieser B-Baumtyp ist noch allgemeiner als ein rot-schwarzer Baum, obwohl, weil er Zweideutigkeit in einer rot-schwarzen Baumkonvertierung erlaubt — vielfache rot-schwarze Bäume von einem gleichwertigen B-Baum des Auftrags 4 erzeugt werden können. Wenn eine B-Baumtraube nur 1 Wert enthält, ist es das minimale, der Schwarze, und hat zwei Kinderzeigestöcke. Wenn eine Traube 3 Werte enthält, dann wird der Hauptwert schwarz sein, und jeder auf seinen Seiten versorgte Wert wird rot sein. Wenn die Traube zwei Werte jedoch enthält, kann jeder der schwarze Knoten im rot-schwarzen Baum werden (und der andere wird rot sein).

So erhält der Auftrag 4 B-Baum nicht aufrecht, welcher von den in jeder Traube enthaltenen Werten die Wurzel schwarzer Baum für die ganze Traube und den Elternteil der anderen Werte in derselben Traube ist. Trotzdem sind die Operationen auf rot-schwarzen Bäumen rechtzeitig mehr wirtschaftlich, weil Sie den Vektoren von Werten nicht aufrechterhalten müssen. Es kann kostspielig sein, wenn Werte direkt in jedem Knoten versorgt werden, anstatt durch die Verweisung versorgt zu werden. B-Baumknoten sind jedoch im Raum mehr wirtschaftlich, weil Sie das Farbenattribut für jeden Knoten nicht zu versorgen brauchen. Statt dessen müssen Sie wissen, welches Ablagefach im Traube-Vektoren verwendet wird. Wenn Werte durch die Verweisung, z.B Gegenstände versorgt werden, können ungültige Verweisungen verwendet werden, und so kann die Traube durch einen Vektoren vertreten werden, der 3 Ablagefächer für Wertzeigestöcke plus 4 Ablagefächer für Kinderverweisungen im Baum enthält. In diesem Fall kann der B-Baum im Gedächtnis kompakter sein, Datengegend verbessernd.

Dieselbe Analogie kann mit B-Bäumen mit größeren Ordnungen gemacht werden, die zu einem farbigen binären Baum strukturell gleichwertig sein können: Sie brauchen gerade mehr Farben. Nehmen Sie an, dass Sie blau, dann der blaue rote schwarze wie rot-schwarze Bäume definierte Baum beitragen, aber mit der zusätzlichen Einschränkung, dass keine zwei aufeinander folgenden Knoten in der Hierarchie blau sein werden und werden alle blauen Knoten Kinder eines roten Knotens sein, dann wird es gleichwertig zu einem B-Baum, dessen Trauben höchstens 7 Werte in den folgenden Farben haben werden: Blau, rot, blau, schwarz, blau, rot, blau (Für jede Traube wird es höchstens 1 schwarzen Knoten, 2 rote Knoten und 4 blaue Knoten geben).

Für gemäßigte Volumina von Werten sind Einfügungen und Auswischen in einem farbigen binären Baum im Vergleich zu B-Bäumen schneller, weil farbige Bäume nicht versuchen, den füllen Faktor jeder horizontalen Traube von Knoten zu maximieren (nur das Minimum füllt sich Faktor wird in farbigen binären Bäumen versichert, die Zahl von Spalten oder Verbindungspunkte von Trauben beschränkend). B-Bäume werden schneller sein, um Folgen durchzuführen (weil Folgen oft innerhalb derselben Traube aber nicht mit vielfachen getrennten Knoten in einem farbigen binären Baum vorkommen werden). Jedoch, um große Volumina zu versorgen, werden B-Bäume viel schneller sein, weil sie kompakter sein werden, indem sie mehrere Kinder in derselben Traube gruppieren werden, wo auf sie lokal zugegriffen werden kann.

Alle in B-Bäumen möglichen Optimierungen, den Durchschnitt zu vergrößern, füllen sich Faktoren von Trauben sind im gleichwertigen binären Mehrfarbenbaum möglich. Namentlich füllt sich Maximierung des Durchschnitts der Faktor in einem strukturell gleichwertigen B-Baum ist dasselbe als das Reduzieren der Gesamthöhe des Mehrfarbenbaums, durch das Steigern der Zahl von nichtschwarzen Knoten. Der Grenzfall kommt vor, wenn alle Knoten in einem farbigen binären Baum schwarz sind, kommt der beste Fall vor, wenn nur ein Drittel von ihnen schwarz ist (und die anderen zwei Drittel rote Knoten sind).

Anwendungen und verwandte Datenstrukturen

Rot-schwarze Bäume bieten Grenzfall-Garantien für die Einfügungszeit, Auswischen-Zeit und Suchzeit an. Nicht nur macht das sie wertvoll in zeitempfindlichen Anwendungen wie Echtzeitanwendungen, aber es macht sie wertvolle Bausteine in anderen Datenstrukturen, die Grenzfall-Garantien zur Verfügung stellen; zum Beispiel können viele in der rechenbetonten Geometrie verwendete Datenstrukturen auf rot-schwarzen Bäumen basieren, und der Völlig Schöne in aktuellen Kernen von Linux verwendete Planer verwendet rot-schwarze Bäume.

Der AVL Baum ist eine andere Struktur, die O unterstützt (loggen Sie n) Suche, Einfügung und Eliminierung. Es wird mehr starr erwogen als rot-schwarze Bäume, zu langsamerer Einfügung und Eliminierung, aber schnellerer Wiederauffindung führend. Das macht es attraktiv für Datenstrukturen, die einmal gebaut und ohne Rekonstruktion, wie Sprachwörterbücher (oder Programm-Wörterbücher, wie der opcodes eines Monteurs oder Dolmetschers) geladen werden können.

Rot-schwarze Bäume sind auch in der funktionellen Programmierung besonders wertvoll, wo sie eine der allgemeinsten beharrlichen Datenstrukturen, verwendet sind, um assoziative Reihe und Sätze zu bauen, die vorherige Versionen nach Veränderungen behalten können. Die beharrliche Version von rot-schwarzen Bäumen verlangt O (loggen Sie n) der Raum für jede Einfügung oder Auswischen, zusätzlich zur Zeit.

Für jeden 2-4 Baum gibt es entsprechende rot-schwarze Bäume mit Datenelementen in derselben Ordnung. Die Einfügung und Auswischen-Operationen auf 2-4 Bäumen sind auch zum Farbenschnipsen und den Folgen in rot-schwarzen Bäumen gleichwertig. Das macht 2-4 Bäume ein wichtiges Werkzeug, für die Logik hinter rot-schwarzen Bäumen zu verstehen, und das ist, warum viele einleitende Algorithmus-Texte 2-4 Bäume kurz vor rot-schwarzen Bäumen einführen, wenn auch 2-4 Bäume in der Praxis nicht häufig verwendet werden.

2008 hat Sedgewick eine einfachere Version des rot-schwarzen Baums eingeführt hat den sich nach links neigenden rot-schwarzen Baum durch das Beseitigen eines vorher unangegebenen Grads der Freiheit in der Durchführung genannt. Der LLRB erhält einen zusätzlichen invariant aufrecht, dass sich alle roten Verbindungen verlassen außer während Einsätze neigen müssen und löschen. Rot-schwarze Bäume können isometrisch entweder zu 2-3 Bäumen oder zu 2-4 Bäumen für jede Folge von Operationen gemacht werden. Die 2-4 Baumisometrie wurde 1978 von Sedgewick beschrieben. Mit 2-4 Bäumen wird die Isometrie durch einen "Farbenflip aufgelöst," entsprechend einem Spalt, in dem die rote Farbe von zwei Kinderknoten die Kinder verlässt und sich zum Elternteilknoten bewegt. Der

Tango-Baum, ein Typ des Baums, der für schnelle Suchen optimiert ist, verwendet gewöhnlich rot-schwarze Bäume als ein Teil seiner Datenstruktur.

Operationen

Read-Only-Operationen auf einem rot-schwarzen Baum verlangen keine Modifizierung von denjenigen, die für binäre Suchbäume verwendet sind, weil jeder rot-schwarze Baum ein spezieller Fall eines einfachen binären Suchbaums ist. Jedoch kann das unmittelbare Ergebnis einer Einfügung oder Eliminierung die Eigenschaften eines rot-schwarzen Baums verletzen. Wiederherstellung der rot-schwarzen Eigenschaften verlangt eine kleine Zahl (O (loggen Sie n) oder amortisierter O (1)) Farbwechsel (die in der Praxis sehr schnell sind), und nicht mehr als drei Baumfolgen (zwei für die Einfügung). Obwohl Einsatz und Operationen löscht, werden kompliziert, ihre Zeiten bleiben O (loggen Sie n).

Einfügung

Einfügung beginnt durch das Hinzufügen des Knotens viel, wie binäre Suchbaumeinfügung tut und durch das Färben davon rot. Wohingegen im binären Suchbaum wir immer hinzufügen, dass ein Blatt, in den rot-schwarzen Baumblättern keine Information enthalten, also stattdessen fügen wir einen roten Innenknoten mit zwei schwarzen Blättern im Platz eines vorhandenen schwarzen Blattes hinzu.

Was geschieht, als nächstes hängt von der Farbe anderer nahe gelegener Knoten ab. Der Begriff-Onkel-Knoten wird verwendet, um sich auf die Geschwister eines Elternteils eines Knotens, als in menschlichen Stammbäumen zu beziehen. Bemerken Sie dass:

  • Eigentum 3 (sind alle Blätter schwarz), hält immer.
  • Eigentum 4 (sind beide Kinder jedes roten Knotens schwarz), wird nur durch das Hinzufügen eines roten Knotens, das Neuanstreichen eines schwarzen Knotens rot, oder eine Folge bedroht.
  • Eigentum 5 (enthalten alle Pfade von jedem gegebenen Knoten bis seine Blatt-Knoten dieselbe Zahl von schwarzen Knoten), wird nur durch das Hinzufügen eines schwarzen Knotens, das Neuanstreichen eines roten Knotens schwarz (oder umgekehrt), oder eine Folge bedroht.

: Referenzen: Das Etikett N wird verwendet, um den aktuellen Knoten (gefärbt rot) anzuzeigen. Am Anfang ist das der neue Knoten, der wird einfügt, aber das komplette Verfahren kann auch rekursiv auf andere Knoten angewandt werden (sieh Fall 3). P wird anzeigen, dass der Elternteilknoten von N, G den Großelternteil von N anzeigen wird, und U den Onkel von N anzeigen wird. Bemerken Sie, dass zwischen einigen Fällen die Rollen und Etiketten der Knoten ausgetauscht werden, aber in jedem Fall setzt jedes Etikett fort, denselben Knoten zu vertreten, den es am Anfang des Falls vertreten hat. Jede im Diagramm gezeigte Farbe wird entweder in seinem Fall angenommen oder durch jene Annahmen einbezogen.

Jeder Fall wird mit dem Beispiel C Code demonstriert. Die Onkel- und Großelternteil-Knoten können durch diese Funktionen gefunden werden:

Struct-Knoten *grandparent (struct Knoten *n)

{\

wenn ((n! = UNGÜLTIG) && (n-> Elternteil! = UNGÜLTIG))

geben Sie n-> Elternteil-> Elternteil zurück;

sonst

kehren Sie UNGÜLTIG zurück;

}\

Struct-Knoten *uncle (struct Knoten *n)

{\

Struct-Knoten *g = Großelternteil (n);

wenn (g == UNGÜLTIG)

kehren Sie UNGÜLTIG zurück;//hat Kein Großelternteil keinen Onkel vor

wenn (n-> Elternteil == g-> verlassen)

geben Sie g-> Recht zurück;

sonst

geben Sie g-> verlassen zurück;

}\</Quelle>

Fall 1: Der aktuelle Knoten N ist an der Wurzel des Baums. In diesem Fall wird es schwarz neu gemalt, um Eigentum 2 zu befriedigen (die Wurzel ist schwarz). Da das einen schwarzen Knoten zu jedem Pfad sofort hinzufügt, Eigentum 5 (enthalten alle Pfade von jedem gegebenen Knoten bis seine Blatt-Knoten dieselbe Zahl von schwarzen Knoten) wird nicht verletzt.

Leere insert_case1 (struct Knoten *n)

{\

wenn (n-> Elternteil == UNGÜLTIG)

n-> färben sich = SCHWARZ;

sonst

insert_case2 (n);

}\</Quelle>

Fall 2: Der Elternteil des aktuellen Knotens P ist schwarz, so wird Eigentum 4 (sind beide Kinder jedes roten Knotens schwarz), nicht ungültig gemacht. In diesem Fall ist der Baum noch gültig. Eigentum 5 (enthalten alle Pfade von jedem gegebenen Knoten bis seine Blatt-Knoten dieselbe Zahl von schwarzen Knoten), wird nicht bedroht, weil der aktuelle Knoten N zwei schwarze Blatt-Kinder hat, aber weil N rot ist, haben die Pfade durch jedes seiner Kinder dieselbe Zahl von schwarzen Knoten wie der Pfad durch das Blatt, das es ersetzt hat, der schwarz war, und so bleibt dieses Eigentum zufrieden.

Leere insert_case2 (struct Knoten *n)

{\

wenn (n-> Elternteil-> färben sich == SCHWARZ)

,

kehren Sie zurück;/*-Baum ist noch * / gültig

sonst

insert_case3 (n);

}\</Quelle>

: Zeichen: In den folgenden Fällen kann es angenommen werden, dass N einen Großelternteil-Knoten G hat, weil sein Elternteil P rot ist, und wenn es die Wurzel wäre, würde es schwarz sein. So, N hat auch einen Onkel-Knoten U, obwohl es ein Blatt in Fällen 4 und 5 sein kann.

Leere insert_case3 (struct Knoten *n)

{\

Struct-Knoten *u = Onkel (n), *g;

wenn ((u! = UNGÜLTIG) && (u-> färben sich == ROT)), {\

n-> Elternteil-> färben sich = SCHWARZ;

u-> färben sich = SCHWARZ;

g = Großelternteil (n);

g-> färben sich = ROT;

insert_case1 (g);

} sonst {\

insert_case4 (n);

}\

}\</Quelle>

: Zeichen: In den restlichen Fällen wird es angenommen, dass der Elternteilknoten P das linke Kind seines Elternteils ist. Wenn es das richtige Kind, verlassen ist und Recht überall in Fällen 4 und 5 umgekehrt werden sollte. Die Codeproben passen darauf auf.

Leere insert_case4 (struct Knoten *n)

{\ Struct-Knoten *g = Großelternteil (n);

wenn ((n == n-> Elternteil-> Recht) && (n-> Elternteil == g-> verlassen)) {\

rotate_left (n-> Elternteil);

n = n-> ist abgereist;

} sonst wenn ((n == n-> Elternteil-> verlassen) && (n-> Elternteil == g-> Recht)) {\

rotate_right (n-> Elternteil);

n = n-> Recht;

}\

insert_case5 (n);

}\</Quelle>

Leere insert_case5 (struct Knoten *n)

{\ Struct-Knoten *g = Großelternteil (n);

n-> Elternteil-> färben sich = SCHWARZ;

g-> färben sich = ROT;

wenn (n == n-> Elternteil-> verlassen)

rotate_right (g);

sonst

rotate_left (g);

}\</Quelle>

Bemerken Sie, dass das Einfügen, seit allen Anrufen über dem Gebrauch-Schwanz recursion wirklich im Platz ist.

Eliminierung

In einem regelmäßigen binären Suchbaum, wenn wir einen Knoten mit zwei Nichtblatt-Kindern löschen, finden wir irgendeinen das maximale Element in seinem linken Subbaum (der ist, um Vorgänger) oder das minimale Element in seinem richtigen Subbaum (der ist, um Nachfolger) und seinen Wert in den Knoten bewegen, der (wie gezeigt, hier) wird löscht. Wir löschen dann den Knoten, von dem wir den Wert kopiert haben, der weniger als zwei Nichtblatt-Kinder haben muss. (Nichtblatt-Kinder, aber nicht alle Kinder, werden hier angegeben, weil verschieden von normalen binären Suchbäumen rot-schwarze Bäume Blatt-Knoten überall haben, können sie sie haben, so dass alle Knoten entweder innere Knoten mit zwei Kindern oder Blatt-Knoten mit, definitionsgemäß, Nullkindern sind. Tatsächlich sind innere Knoten, die zwei Blatt-Kinder in einem rot-schwarzen Baum haben, den Blatt-Knoten in einem regelmäßigen binären Suchbaum ähnlich.) Weil bloß das Kopieren eines Werts keine rot-schwarzen Eigenschaften verletzt, nimmt das zum Problem ab, einen Knoten mit höchstens einem Nichtblatt-Kind zu löschen. Sobald wir dieses Problem behoben haben, gilt die Lösung ebenso für den Fall, wo der Knoten, den wir ursprünglich löschen wollen, höchstens ein Nichtblatt-Kind betreffs des Falls hat, gerade hat gedacht, wo es zwei Nichtblatt-Kinder hat.

Deshalb für den Rest dieser Diskussion richten wir das Auswischen eines Knotens mit höchstens einem Nichtblatt-Kind. Wir verwenden das Etikett M, um den zu löschenden Knoten anzuzeigen; C wird ein ausgewähltes Kind der M anzeigen, die wir auch "sein Kind" nennen werden. Wenn M wirklich ein Nichtblatt-Kind hat, nennen Sie dieses sein Kind, C; wählen Sie sonst jedes Blatt als sein Kind, C.

Wenn M ein roter Knoten ist, ersetzen wir sie einfach durch sein Kind C, das durch das Eigentum 4 schwarz sein muss. (Das kann nur vorkommen, wenn M zwei Blatt-Kinder, weil hat, wenn der rote Knoten M ein schwarzes Nichtblatt-Kind auf einer Seite hatte, aber gerade würde ein Blatt-Kind auf der anderen Seite, dann würde die Zählung von schwarzen Knoten an beiden Seiten, so der Baum verschieden sein, Eigentum 5 verletzen.) Werden alle Pfade durch den gelöschten Knoten einfach einen weniger roten Knoten durchführen, und sowohl der Elternteil als auch Kind des gelöschten Knotens müssen schwarz sein, so halten Eigentum 3 (sind alle Blätter schwarz), und Eigentum 4 (sind beide Kinder jedes roten Knotens schwarz), noch.

Ein anderer einfacher Fall ist, wenn M schwarz ist und C rot ist. Einfach das Entfernen eines schwarzen Knotens konnte brechen Eigenschaften 4 ("Beide Kinder jedes roten Knotens sind" schwarz), und 5 ("Alle Pfade von jedem gegebenen Knoten bis seine Blatt-Knoten enthalten dieselbe Zahl von schwarzen Knoten"), aber wenn wir C Schwarzen neu malen, werden beide dieser Eigenschaften bewahrt.

Der komplizierte Fall ist, wenn sowohl M als auch C schwarz sind. (Das kann nur vorkommen, wenn es einen schwarzen Knoten löscht, der zwei Blatt-Kinder hat, weil, wenn der schwarze Knoten M ein schwarzes Nichtblatt-Kind auf einer Seite hatte, aber gerade würde ein Blatt-Kind auf der anderen Seite, dann würde die Zählung von schwarzen Knoten an beiden Seiten, so der Baum verschieden sein, ein ungültiger rot-schwarzer Baum durch die Übertretung des Eigentums 5 gewesen war.) Wir beginnen, indem wir M durch sein Kind C. ersetzen. Wir werden rufen (oder Etikett - d. h. Wiederetikett) dieses Kind (in seiner neuen Position) N und seinen Geschwister (das andere Kind seines neuen Elternteils) S. (S war vorher die Geschwister von M.)

In den Diagrammen unten werden wir auch P für den neuen Elternteil von N (Der alte Elternteil der M) verwenden, S für das linke Kind von S und S für das richtige Kind von S (S kann kein Blatt sein, weil, wenn N schwarz ist, den wir dann gewagt haben, ein Subbaum von P, der N einschließt, zwei schwarze Höhe und so den anderen Subbaum von P aufzählt, der S einschließt, muss auch zwei schwarze Höhe aufzählen, die nicht der Fall sein kann, wenn S ein Blatt-Knoten ist).

: Referenzen: Zwischen einigen Fällen tauschen wir die Rollen und Etiketten der Knoten aus, aber in jedem Fall setzt jedes Etikett fort, denselben Knoten zu vertreten, den es am Anfang des Falls vertreten hat. Jede im Diagramm gezeigte Farbe wird entweder in seinem Fall angenommen oder durch jene Annahmen einbezogen. Weiß vertritt eine unbekannte Farbe (entweder rot oder schwarz).

Wir werden die Geschwister finden, die diese Funktion verwenden:

Struct-Knoten *sibling (struct Knoten *n)

{\

wenn (n == n-> Elternteil-> verlassen)

geben Sie n-> Elternteil-> Recht zurück;

sonst

geben Sie n-> Elternteil-> verlassen zurück;

}\</Quelle>

: Referenzen: Damit der Baum bestimmt bleibt, brauchen wir dieses jedes ungültige Blatt bleibt ein Blatt nach allen Transformationen (dass es keine Kinder haben wird). Wenn der Knoten, den wir löschen, ein Nichtblatt (nichtungültiges) Kind N hat, ist es leicht zu sehen, dass das Eigentum zufrieden ist. Wenn, andererseits, N ein ungültiges Blatt sein würde, kann er aus den Diagrammen (oder Code) für alle Fälle nachgeprüft werden, dass das Eigentum ebenso zufrieden ist.

Wir können die Schritte durchführen, die oben mit dem folgenden Code entworfen sind, wo die Funktion in 's Platz im Baum vertritt. Für die Bequemlichkeit wird der Code in dieser Abteilung annehmen, dass ungültige Blätter durch wirkliche Knotengegenstände vertreten aber nicht (der Code in den Einfügungsabteilungsarbeiten mit jeder Darstellung) UNGÜLTIG WERDEN.

Leere delete_one_child (struct Knoten *n)

{\

/ *

* Vorbedingung: N hat am grössten Teil eines nichtungültigen Kindes.

*/

Struct-Knoten *child = is_leaf (n-> Recht)? n-> ist abgereist: n-> Recht;

replace_node (n, Kind);

wenn (n-> färben sich == SCHWARZ), {\

wenn (Kind-> färben sich == ROT)

,

Kind-> färbt sich = SCHWARZ;

sonst

delete_case1 (Kind);

}\

frei (n);

}\</Quelle>

: Referenzen: Wenn N ein ungültiges Blatt ist und wir ungültige Blätter nicht vertreten wollen, weil wirklicher Knoten protestiert, können wir den Algorithmus durch das erste Benennen delete_case1 auf seinem Elternteil modifizieren (der Knoten, den wir, im Code oben löschen), und das Löschen davon später. Wir können das tun, weil der Elternteil schwarz ist, so benimmt es sich ebenso als ein ungültiges Blatt (und manchmal ein 'Gespenst'-Blatt genannt wird). Und wir können es am Ende sicher löschen, wie ein Blatt nach allen Operationen, wie gezeigt, oben bleiben wird.

Wenn sowohl N als auch sein ursprünglicher Elternteil schwarz sind, dann verursacht das Löschen dieses ursprünglichen Elternteils Pfade, die durch N fortfahren, denjenigen weniger schwarzer Knoten zu haben, als Pfade, die nicht tun. Da das Eigentum 5 verletzt (alle Pfade von jedem gegebenen Knoten bis seine Blatt-Knoten enthalten dieselbe Zahl von schwarzen Knoten), der Baum muss wiedererwogen werden. Es gibt mehrere Fälle, um in Betracht zu ziehen:

Fall 1: N ist die neue Wurzel. In diesem Fall werden wir getan. Wir haben einen schwarzen Knoten von jedem Pfad entfernt, und die neue Wurzel ist schwarz, so werden die Eigenschaften bewahrt.

Leere delete_case1 (struct Knoten *n)

{\

wenn (n-> Elternteil! = UNGÜLTIG)

delete_case2 (n);

}\</Quelle>

: Referenzen: In Fällen 2, 5, und 6, nehmen wir an, dass N das linke Kind seines Elternteils P. ist. Wenn es das richtige Kind, verlassen ist und Recht überall in diesen drei Fällen umgekehrt werden sollte. Wieder ziehen die Codebeispiele beide Fälle in Betracht.

Leere delete_case2 (struct Knoten *n)

{\

Struct-Knoten *s = Geschwister (n);

wenn (s-> färben sich == ROT), {\

n-> Elternteil-> färben sich = ROT;

s-> färben sich = SCHWARZ;

wenn (n == n-> Elternteil-> verlassen)

rotate_left (n-> Elternteil);

sonst

rotate_right (n-> Elternteil);

}

delete_case3 (n);

}\</Quelle>

Leere delete_case3 (struct Knoten *n)

{\ Struct-Knoten *s = Geschwister (n);

wenn ((n-> Elternteil-> färben sich == SCHWARZ)

, &&

(s-> färben sich == SCHWARZ)

&&

(s-> nach links> färben sich == SCHWARZ)

&&

(s-> Recht-> färben sich == SCHWARZ)) {\

s-> färben sich = ROT;

delete_case1 (n-> Elternteil);

} sonst

delete_case4 (n);

}\</Quelle>

Leere delete_case4 (struct Knoten *n)

{\ Struct-Knoten *s = Geschwister (n);

wenn ((n-> Elternteil-> färben sich == ROT)

, && (s-> färben sich == SCHWARZ) && (s-> nach links> färben sich == SCHWARZ) && (s-> Recht-> färben sich == SCHWARZ)) {\ s-> färben sich = ROT; n-> Elternteil-> färben sich = SCHWARZ; } sonst

delete_case5 (n);

}\</Quelle>

Leere delete_case5 (struct Knoten *n)

{\ Struct-Knoten *s = Geschwister (n);

wenn (s-> färben sich == SCHWARZ) {/* das, wenn Behauptung, trivial

ist

wegen des Falls 2 (wenn auch Fall 2 die Geschwister einem Kind ein Geschwister, geändert

hat

das Kind der Geschwister kann nicht rot sein, da kein roter Elternteil ein rotes Kind haben kann). * /

/* die folgenden Behauptungen zwingen gerade das Rot, auf dem verlassenen des verlassenen des Elternteils, zu sein

oder das Recht auf das Recht, so wird Fall sechs richtig rotieren. * /

wenn ((n == n-> Elternteil-> verlassen)

&&

(s-> Recht-> färben sich == SCHWARZ)

&&

(s-> nach links> Farbe == ROT)) {/* dieser letzte Test ist zu wegen Fälle 2-4 trivial. * /

s-> färben sich = ROT;

s-> nach links> färben sich = SCHWARZ;

rotate_right (s);

} sonst wenn ((n == n-> Elternteil-> Recht)

&&

(s-> nach links> färben sich == SCHWARZ)

&&

(s-> Recht-> Farbe == ROT)) {/* dieser letzte Test ist zu wegen Fälle 2-4 trivial. * /

s-> färben sich = ROT;

s-> Recht-> färben sich = SCHWARZ;

rotate_left (s);

}\

}\

delete_case6 (n);

}\</Quelle>

Leere delete_case6 (struct Knoten *n)

{\ Struct-Knoten *s = Geschwister (n);

s-> färben sich = n-> Elternteil-> Farbe;

n-> Elternteil-> färben sich = SCHWARZ;

wenn (n == n-> Elternteil-> verlassen) {\

s-> Recht-> färben sich = SCHWARZ;

rotate_left (n-> Elternteil); } sonst {\

s-> nach links> färben sich = SCHWARZ;

rotate_right (n-> Elternteil); }\}\</Quelle>

Wieder nennt die Funktion den ganzen Gebrauch-Schwanz recursion, so ist der Algorithmus in dem Platz.

Im Algorithmus oben werden alle Fälle in der Ordnung gekettet, außer darin löschen Fall 3, wo es wiederfluchen kann, um 1 zurück zum Elternteilknoten zu umgeben: Das ist der einzige Fall, wo sich eine Durchführung im Platz (nach nur einer Folge im Falle dass 3) effektiv schlingen wird.

Zusätzlich kommt kein Schwanz recursion jemals auf einem Kinderknoten vor, so kann sich der Schwanz recursion Schleife nur von einem Kind zurück seinen aufeinander folgenden Vorfahren bewegen. Nicht mehr als O (loggen n), werden Schleifen zurück, um 1 zu umgeben, vorkommen (wo n die Gesamtzahl von Knoten im Baum vor dem Auswischen ist). Wenn eine Folge vorkommt, im Falle dass 2 (der die einzige Möglichkeit der Folge innerhalb der Schleife von Fällen 1-3 ist), dann wird der Elternteil des Knotens N rot danach, der Folge und wir über die Schleife herrschen wird. Deshalb höchstens wird eine Folge innerhalb dieser Schleife vorkommen. Da nicht mehr als zwei zusätzliche Folgen nach dem Herausnehmen über die Schleife vorkommen werden, höchstens kommen drei Folgen insgesamt vor.

Beweis von asymptotischen Grenzen

Ein roter schwarzer Baum, der n innere Knoten enthält, hat eine Höhe von O (Klotz (n)).

Definitionen:

  • h (v) = hat die Höhe des Subbaums am Knoten v eingewurzelt
  • bh (v) = die Zahl von schwarzen Knoten (v nicht zählend, wenn es schwarz ist) von v bis jedes Blatt im Subbaum (hat die schwarze Höhe genannt).

Lemma: Ein Subbaum, der am Knoten v eingewurzelt ist, hat mindestens innere Knoten.

Beweis des Lemmas (durch die Induktionshöhe):

Basis: h (v) = 0

Wenn v eine Höhe der Null dann hat, muss es, deshalb bh (v) = 0 ungültig sein. So:

:

2^ {bh (v)}-1 = 2^ {0}-1 = 1-1 = 0

</Mathematik>

Induktiver Schritt: v solch dass h (v) = k, hat mindestens innere Knoten deutet an, dass solch, dass h = k+1 mindestens innere Knoten hat.

Seitdem hat h > 0 es ist ein innerer Knoten. Als solcher hat es zwei Kinder, von denen jedes eine schwarze Höhe von irgendeinem bh oder bh -1 haben (je nachdem, ob das Kind rot oder, beziehungsweise schwarz ist). Durch die induktive Hypothese hat jedes Kind mindestens innere Knoten, so hat mindestens:

:

2^ {bh (v')-1}-1 + 2^ {bh (v')-1}-1 + 1 = 2^ {bh (v')}-1

</Mathematik>

innere Knoten.

Das Verwenden dieses Lemmas wir können jetzt zeigen, dass die Höhe des Baums logarithmisch ist. Seit der mindestens Hälfte der Knoten auf jedem Pfad von der Wurzel bis ein Blatt sind schwarz (Eigentum 4 eines rot-schwarzen Baums), die schwarze Höhe der Wurzel ist mindestens h (Wurzel)/2. Durch das Lemma kommen wir:

:

n \geq 2^ - 1 \leftrightarrow \; \log_2 {(n+1)} \geq {h (\text {Wurzel}) \over 2} \leftrightarrow \; h (\text {Wurzel}) \leq 2\log_2 {(n+1)}.

</Mathematik>

Deshalb ist die Höhe der Wurzel O (Klotz (n)).

Einfügungskompliziertheit

Im Baumcode gibt es nur eine Schleife, wo der Knoten der Wurzel des rot-schwarzen Eigentums, das wir, x wieder herstellen möchten, der Baum durch ein Niveau bei jeder Wiederholung herangebracht werden kann.

Da die ursprüngliche Höhe des Baums O ist (loggen Sie n), es gibt O (loggen Sie n) Wiederholungen. So insgesamt hat die Einsatz-Routine O (loggen Sie n) Kompliziertheit.

Parallele Algorithmen

Parallele Algorithmen, um rot-schwarze Bäume von sortierten Listen von Sachen zu bauen, können in der unveränderlichen Zeit oder O (loglog n) Zeit abhängig vom Computermodell führen, wenn die Zahl von verfügbaren Verarbeitern zur Zahl von Sachen proportional ist. Schnelle Suche, Einfügung und Auswischen-Parallele-Algorithmen sind auch bekannt.

Siehe auch

Referenzen

Links

http://java.sun.com/docs/books/tutorial/collections/interfaces/set.html C#

Verschlüsselung der Lauf-Länge / RMS Laconia
Impressum & Datenschutz