POLITECHNIKA WARSZAWSKA Instytut Automatyki i Robotyki ZASADY PROGRAMOWANIA KOMPUTERÓW ZAP zima 204/205 Język programowania: Środowisko programistyczne: C/C++ Qt Wykład 2 : Drzewa BST c.d., równoważenie drzew, kopce.
Wyświetlanie drzewa BST - c.d. 2 void WyswietlDrzewo (Twezel *wezel) { // porządek preorder if (wezel!= NULL) { cout << wezel->dane << " "; WyswietlDrzewo (wezel->lewy); WyswietlDrzewo (wezel->prawy); } } Kolejność wyświetlania wartości w węzłach: 5,, 2,, 4, 8, 6,, 9 void WyswietlDrzewo (Twezel *wezel) { // porządek postorder if (wezel!= NULL) { WyswietlDrzewo (wezel->lewy); WyswietlDrzewo (wezel->prawy); cout << wezel->dane << " "; } } Kolejność wyświetlania wartości w węzłach:, 2, 4,,, 6, 9, 8, 5
Poszukiwanie węzła w drzewie BST bool ZnajdzWezel (Twezel* wezel, int wartosc) { // funkcja zwraca wartość true, jeżeli udało się jej znaleźć // wartość, w przeciwnym razie zwraca wartość false if (wezel == NULL) return false; else if (wartosc < wezel->dane) return ZnajdzWezel (wezel->lewy, wartosc); else if (wartosc > wezel->dane) return ZnajdzWezel (wezel->prawy, wartosc); else return true; }
Poszukiwanie węzła c.d., usuwanie całego drzewa BST 4 porównaj z rekurencyjną procedurą usuwania listy (s. 6 wykładu ) void UsunDrzewo (Twezel *&wezel) { Twezel *pom; if (wezel!= NULL) { UsunDrzewo (wezel->lewy); UsunDrzewo (wezel->prawy); pom = wezel; wezel = NULL; delete pom; } }
Algorytm usuwania węzła w drzewie BST 5 Należy usunąć węzeł o podanej wartości. Mogą wystąpić przypadki:. Brak takiego węzła 2. Węzeł usuwany ma co najwyżej jednego potomka ( może też być liściem drzewa ) Adres usuwanego węzła zastępuje się adresem jego potomka ( lub NULL ). Węzeł usuwany ma dwóch potomków a) Usuwany węzeł zostaje zastąpiony przez skrajny prawy węzeł jego lewego poddrzewa (czyli największy element lewego poddrzewa) lub: b) Usuwany węzeł zostaje zastąpiony przez skrajny lewy węzeł jego prawego poddrzewa (czyli najmniejszy element prawego poddrzewa) UWAGA : Zastąpienie takie zawsze jest możliwe, bo skoro węzeł jest skrajny, to ma co najwyżej jednego potomka. UWAGA 2: Każdą z operacji a) i b) da się więc wykonać, najlepiej je wykonywać losowo (lub na przemian). Przypadek 2. 5 Przypadek. 5 8 8 2 4 6 9 2 4 6 9
Przykład - usuwanie węzłów 6 węzeł usuwany węzeł zajmujący miejsce węzła usuwanego 5 5 8 8 2 4 6 9 4 6 9 2 5 6 9 9 4 6 4 4
Drzewa zrównoważone - wprowadzenie Struktura drzewa BST zależy od kolejności, w jakiej zostały utworzone węzły. Nowe węzły wstawiane są jako liście drzewa 5 8 2 4 6 9 Kolejność tworzonych węzłów drzewa BST: 5,, 8, 2, 6, 4, 9,, lub 5, 8, 9,, 6, 2, 4,, lub... 2 4 5 Kolejność tworzonych węzłów:, 2,, 4, 5, 6,, 8, 9 6 8 9 Ilość poziomów (wysokość drzewa): 4 Ilość poziomów (wysokość drzewa): 9 Drzewa wyważone ( zrównoważone ) Zapewniają optymalny stosunek ilości poziomów do ilości węzłów Przykłady: drzewa AVL, drzewa czerwono-czarne (RBT).
Operacje rotacji - przywracanie wyważenia węzła drzewa 8 a, b, d - dowolne poddrzewa // rotacja w prawo względem Q if (Q->Lewy == P) { Q->Lewy = P->Prawy; P-> Prawy = Q; Q = P; // nowym korzeniem // tego poddrzewa będzie teraz P } Operacje rotacji zachowują porządek inorder // rotacja w lewo względem P if (P->Prawy == Q) { P-> Prawy = Q-> Lewy; Q-> Lewy = P; P = Q; // nowym korzeniem // tego poddrzewa będzie teraz Q }
Aplet Drzewo binarne - równoważenie drzewa 9 Wskaźniki wyważenia w węzłach (bezwzględna różnica wysokości) uzyskuje się zaznaczając opcję wagi Rys. 2. Drzewo zrównoważone - po wykonaniu rotacji w prawo względem węzła=4 (bo zaznaczamy prawym przyciskiem myszki prawego potomka węzła 4, czyli węzeł =) Rys.. Drzewo początkowe - niezrównoważone Bardzo często trzeba wykonać więcej rotacji, by uzyskać drzewo zrównoważone. Maksymalna liczba koniecznych rotacji dla drzewa o n węzłach jest rzędu lg(n).
Definicja drzewa AVL (Adelson-Velskij i Landis, 962 r.) 0 Drzewo dokładnie wyważone Dla każdego węzła ilość węzłów jego lewego i prawego poddrzewa może różnić się tylko o jeden Drzewo wyważone AVL Dla każdego węzła wysokość jego lewego i prawego poddrzewa może się różnić tylko o jeden Wskaźnik wyważenia węzła Wsk = H P H L w w w Wskaźnik wyważenia węzła, czyli różnica wysokości dla lewego i prawego jego poddrzewa, jest pamiętany w węźle. H L Wsk > 0 H P H L H P H P H L Wsk = 0 Wsk < 0 Przykłady 5 0 5 + 5 +2 5 + - 8 - + 8-0 8 - + 8-2 6 + 2-4 0 9 0 4 0 9 0 6 + 6 + 9 0 4 0 6 + 0 Drzewo AVL 0 Drzewo AVL 0 0 Drzewo niewyważone 0 Drzewo niewyważone 0
Drzewa czerwono-czarne (RBT - Red Black Tree), 92-8 r. (R. J. Guibas, R. Sedgewick) Drzewo czerwono-czarne Drzewo wyszukiwań binarnych, w którym każdy węzeł zawiera dodatkowe pole Kolor ( bit), który może być czerwony (Red) lub czarny (Black). Narzucenie odpowiednich warunków na kolory w węzłach gwarantuje, że drzewo jest w przybliżeniu zrównoważone, a przywrócenie jego własności wymaga co najwyżej dwóch operacji rotacji (!). Własności drzew RBT Drzewo BST jest drzewem czerwono-czarnym (RBT), jeśli ma następujące własności czerwono-czarne: * każdy węzeł jest albo czerwony, albo czarny * korzeń jest czarny * każdy liść (NULL) jest czarny * jeśli węzeł jest czerwony, to obaj jego synowie są czarni (a zatem każdy czerwony węzeł ma czarnego ojca) * każda prosta ścieżka z ustalonego węzła do dowolnego liścia ma tyle samo czarnych węzłów (jest to tzw. czarna głębokość węzła).
Drzewa czerwono-czarne pochylone w lewo - 2008 r. 2 Prostszy sposób rysowania drzew RBT - bez liści, bo wiadomo, że wszystkie liście są czarne i nie zawierają istotnych danych. Autor: Robert Sedgewick, Princeton University Drzewa LLRBT (Left Leaning Red Black Trees) algorytmy bardzo uproszczone względem RBT (kosztem większej liczby koniecznych rotacji), dzięki dodatkowej własności: * Prawy syn jest czerwony tylko i wyłącznie wtedy, gdy czerwony jest również lewy syn. Najkrótsza ścieżka w drzewach RBT ma wszystkie węzły czarne, najdłuższa- czarne i czerwone na przemian. Każda gałąź jest więc co najwyżej dwa razy dłuższa niż dowolna inna (bo na każdej musi być tyle samo czarnych węzłów). Wysokość drzewa RBT o n węzłach wewnętrznych wynosi co najwyżej 2lg (n+) Operacje wstawiania węzła i usuwania węzła wykonują się w czasie proporcjonalnym do lg n Przewaga drzew czerwono-czarnych nad drzewami AVL polega na tym, że RBT w tych najgorszych przypadkach wymagają mniej operacji rotacji podczas wstawiania lub usuwania węzła. Natomiast drzewa AVL lepiej się sprawdzają w operacjach wyszukiwania (bo są lepiej wyważone).
Zastosowanie drzew binarnych - drzewa wyrażeń Bryły CSG - reprezentowane przez drzewa wyrażeń (bryły podstawowe w liściach + operacje logiczne w węzłach)
Kopiec czyli sterta 4 Jeśli i oznacza indeks węzła, to indeks ojca wynosi i/2, czyli część całkowitą z połowy wartości i indeks lewego potomka wynosi 2i indeks prawego potomka wynosi 2i+ Służy do implementacji kolejki priorytetowej, która pozwala usunąć z kolejki element o największym kluczu Każdy element w węźle ma wartość nie większą niż jego ojciec największy element jest więc zawsze na pozycji korzenia, a elementy w kopcu mogą się powtarzać Każdy poziom drzewa poza ostatnim jest całkowicie wypełniony
Wstawianie elementu do kopca i przywracanie własności kopca () 5 wstaw krok wstaw krok 2 najpierw dodajemy wstawiany element jako nowy liść na najniższym poziomie następnie, w razie potrzeby, przesuwamy ten element na wyższe poziomy (zamieniając z kolejnymi ojcami), aż do momentu, gdy całe drzewo będzie posiadało własność kopca
Wstawianie elementu do kopca i przywracanie własności kopca (2) 6 wstaw krok Sortowanie przez kopcowanie (heapsort) pobranie największego elementu i zamiana z ostatnim elementem zmniejszenie rozmiaru kopca i przywrócenie jego własności (zamiana ojca z większym z synów wykonywana rekurencyjnie od korzenia w dół) pobranie największego elementu itd.