Drzewo RB to drzewo BST, w którym każdy wierzchołek posiada dodatkowe pole "kolor" i które posiada tzw własności czerwono-czarne:
UWAGA 2: 
Wszystkie operacje z drzew BST (za wyjątkiem wstawiania i 
usuwania wierzchołków) można przenieść na drzewa RB.  Operacje 
BST_WstawWierz() i BST_UsunWierz() zniszczyłyby własności czerwono-czarne !. 
UWAGA 3: 
Z własności czerwono-czarnych 3 i 4 wynika że ścieżki łączące 
korzeń i liście mają długości różniące się co najwyżej o czynnik 2.  
Dlatego właśnie drzewo RB jest w przybliżeniu zrównoważone i ma wysokość O(log 
n). 
DEF: liczbę czarnych wierzchołkow na dowolnej ścieżce od wierz "x" do 
liścia (wykluczając "x") nazywamy czarną wysokością wierzchołka "x". 
  
  
Wierzchołek drzewa RB reprezentujemy przy pomocy struktury:
struct RB_Wierz {
  int klucz;
  RB_Wierz *ojciec, *lewy, *prawy;
  int kolor;
};
const int CZERWONY=0;
const int CZARNY=1;Naszym celem jest zaprogramować operację: RB_WstawWierz(RB_wierz *&korzen, int klucz);Zaczniemy od zaprogramowania pomocniczych operacji:
RB_RotacjaWLewo(RB_wierz *x); RB_RotacjaWPrawo(RB_wierz *x);których działanie zilustrowano na rysunku:
 
 
Zadanie 16 
BST_RotacjaWLewo(BST_wierz *x); BST_RotacjaWPrawo(BST_wierz *x);i sprawdz je na zwykłym drzewie BST z lekcji 6. Użyj procedury BST_PokazDrzewo() aby przekonać się że wszystko jest OK. Potem zamień "BST" na "RB".
W pętli tej rozpatruje się 3 przypadki: w 1 przypadku zmienna "x" przemieszcza się w kierunku korzenia, w 2 i 3 przypadku pętla się kończy (przypadki są dokładnie wyjaśnione na rysunkach).
Pętla "kręci się" jeśli "x" nie jest korzeniem i jeśli kolor jego ojca jest czerwony.
W pętli rozpatrujemy 2 możliwości: gdy ojciec "x"-a jest lewym synem dziadka lub gdy jest prawym synem dziadka. Omówimy tylko sytuacje gdy jest lewym synem dziadka (w drugim przypadku postępuje się podobnie - należy tylko zamienić miejscami strony lewą i prawą).
Wszystkie 3 przypadki (razy 2 możliwości) które należy rozpatrywać w 
  każdym obrocie pętli są przedstawione na poniższych  rysunkach 
. 
UWAGA 2: 
Zauważ że operacje jakie wykonujemy na drzewie (patrz rysunki) 
zachowują własność 4. 
Wprowadźmy oznaczenia: 
        
y   -stryj wierzchołka x  (y=x->ojciec->ojciec->prawy) 
        x1 -ojciec wierzchołka x 
        x2 -dziadek wierzchołka x 
(x, 
x1, x2, y - są wskazaniami na wierzchołki !) 
  
Przypadek 1: 
zachodzi gdy "y->kolor == CZERWONY" 
nie ma 
znaczenia czy "x" jest lewym czy prawym synem x1 
zmieniamy kolory 
wierzchołków x1, y, x2 
(przekłamanie nie zostaje usunięte !) 
zmienna "x" 
przemieszcza się w kierunku korzenia: przypisanie x=x2  
  
  
Przypadek 2: 
zachodzi gdy "y->kolor == CZARNY" oraz gdy "x" 
jest prawym synem swojego ojca 
wykonujemy rotacje w lewo względem x1  
następnie przypisujemy x=x1 
otrzymujemy sytuację dopuszczalną przez 
przypadek 3 i wykonujemy jego kod 
(przekłamanie zostaje usunięte 
definitywnie - koniec pętli)  
 
  
Przypadek 3: 
zachodzi gdy "y->kolor == CZARNY" oraz gdy "x" 
jest lewym synem swojego ojca 
zmieniamy kolory wierzchołków x1 i x2 (krok 1) 
następnie dokonujemy rotacji w prawo względem x2 (krok2) 
(przekłamanie 
zostaje usunięte definitywnie - koniec pętli)  
 
  
 
Zadanie 17 
RB_WstawWierz(RB_wierz *&korzen, int klucz); RB_PokazDrzewo(RB_wierz *korzen);Sprawdz czy procedura RB_WstawWierz() działa prawidłowo, przy pomocy RB_PokazDrzewo(). Procedura RB_PokazDrzewo() powinna pokazywać wierzchołki drzewa w następujący sposób:
klucz(klucz_ojca)[kolor], ...
Zadanie domowe 8 
RB_UsunWierz(RB_wierz *&korzen, RB_wierz *x);oraz
RB_Wysokosc(RB_wierz *x, int &min, int &max); RB_WysokoscCzarna(RB_wierz *x, int &min, int &max);oraz zmodyfikuj procedury dla drzew BST tak aby działaly dla drzew RB.
Sprawdz czy procedura RB_UsunWierz() działa, przy pomocy RB_PokazDrzewo().
Procedury RB_Wysokosc() i RB_WysokoscCzarna() zwracają długość najdłuższej i 
najkrótszej ścieżki od wierzchołka "x" do liści.  W przypadku drugiej 
procedury chodzi tylko o ilość czarnych wierzchołków (wykluczając "x") w każdej 
takiej ścieżce.  Jeśli uruchomimy te procedury dla korzenia oraz jeśli 
wszystko działa poprawnie to w przypadku RB_Wysokosc() powinno być: 
"max<=2*min", natomiast w przypadku RB_WysokoscCzarna() powinno być 
"max==min". 
  
Zadanie domowe 9