Binary Search Tree (BST)

by Jerry Sky

2020-03-25



Description

Drzewa poszukiwań binarnych (ukorzenione drzewa, każdy węzeł ma dwóch potomków, liście mają zero potomków) są strukturami danych, na których można wykonywać różne operacje na zbiorach dynamicznych takie jak Search, Minimum, Maximum, Predecessor, Successor, Insert, Delete\mathrm{Search},~\mathrm{Minimum},~\mathrm{Maximum},~\mathrm{Predecessor},~\mathrm{Successor},~\mathrm{Insert},~\mathrm{Delete}.

Węzeł drzewa

Węzeł drzewa składa się z:

  1. key\mathrm{key} - wartość ze zbioru dynamicznego AA, którą możemy porównać z każdym innym elementem należącym do AA
  2. left\mathrm{left} - wskaźnik na lewego potomka
  3. right\mathrm{right} - wskaźnik na prawego potomka
  4. parent\mathrm{parent} - wskaźnik na rodzica (opcjonalny)

Porządek w BST

Niech xx będzie węzłem BST TT. Jeśli yy \in lewe pod-drzewo xx wtedy y.keyx.keyy.\mathrm{key} \le x.\mathrm{key}, w przeciwnym przypadku y.keyx.keyy.\mathrm{key} \ge x.\mathrm{key}.

Wysokość BST

Istotnym parametrem BST jest jego wysokość hh, czyli najdłuższa ścieżka między korzeniem drzewa, a liściem.

Operacje dla BST

InorderTreeWalk\mathrm{InorderTreeWalk}

Operacja pozwalająca na przechodzenie drzewa w uporządkowany sposób. Operacja ta wywołana na drzewie o nn węzłach ma złożoność obliczeniową Θ(n)\Theta(n).

Search(x)\mathrm{Search}(x)

Operacja pozwalająca wyszukać węzeł w drzewie BST, którego pole key==x\mathrm{key} == x.
Jeśli taki element nie istnieje to zwraca null\mathrm{null}.
Operacja ta ma złożoność obliczeniową O(h)O(h) gdzie hh to wysokość BST.

Insert(x)\mathrm{Insert}(x)

Operacja wstawiająca nowy węzeł do BST, którego pole key:=x\mathrm{key} := x.
Operacja ta zachowuje oczywiście porządek w BST do którego wstawiany jest nowy element.
Operacja ta ma złożoność obliczeniową O(h)O(h).

Delete(x)\mathrm{Delete}(x)

Operacja usuwająca element xx z BST.
Operacja ta jest bardziej złożona niż poprzednie, należy w niej rozpatrzeć czy usuwany węzeł jest:

Operacja ta zachowuje oczywiście porządek w BST, z którego usuwany jest węzeł xx.
Operacja ta ma złożoność obliczeniową O(h)O(h).

Minimum\mathrm{Minimum}

Operacja zwraca element BST o najmniejszej wartości pola key\mathrm{key}, czyli element „najbardziej po lewej stronie w drzewie”.
Operacja ta ma złożoność obliczeniową O(h)O(h).

Maximum\mathrm{Maximum}

Operacja zwraca element BST o największej wartości pola key\mathrm{key}, czyli element „najbardziej po prawej stronie w drzewie”.
Operacja ta ma złożoność obliczeniową O(h)O(h).

Successor(x)\mathrm{Successor}(x)

Operacja zwraca węzeł BST, którego wartość pola key\mathrm{key} jest następnikiem węzła xx, czyli węzeł o najmniejszej wartości pola key\mathrm{key} większej niż x.keyx.\mathrm{key} (zakładając, że wszystkie klucze w drzewie są różne). Operacja ta ma złożoność obliczeniową O(h)O(h).

Predecessor(x)\mathrm{Predecessor}(x)

Operacja analogiczna do Successor\mathrm{Successor}, zwracająca poprzednika węzła xx.

BSTSort\mathrm{BSTSort}

Rozpatrzmy operację BSTSort\mathrm{BSTSort}, która wstawia do BST wszystkie elementy zbioru A=(a1,,an)A=(a_1,\dots,a_n), a następnie wykonuje na tym drzewie InorderTreeWalk\mathrm{InorderTreeWalk}.
Wynikiem będzie wypisanie posortowanego ciągu elementów ze zbioru AA. Warto zauważyć, że BSTSort\mathrm{BSTSort} wykonuje te same porównania co QuickSort\mathrm{QuickSort} wykonany na zbiorze AA (tylko może w innej kolejności).

Załóżmy, że wejściem do naszego algorytmu jest losowa permutacja elementów tablicy AA.
Wiedząc z wcześniejszego wykładu, że w QuickSort\mathrm{QuickSort}cie E(#poroˊwnanˊ)=Θ(nlogn)E(\#\text{porównań}) = \Theta(n\log n).
W takim razie dla BST: E(sˊrednia głębokosˊcˊ węzła w drzewie BST)=Θ(logn) \mathrm{E}(\text{średnia głębokość węzła w drzewie BST}) = \Theta(\log n) gdzie głębokością węzła xx w BST jest jego odległość od korzenia drzewa.
Niestety, z tego faktu nie możemy wywnioskować, że wysokość drzewa jest również logarytmiczna (istnieje drzewo o średniej głębokości węzła Θ(logn)\Theta(\log n) oraz wysokości Θ(n)\Theta\left(\sqrt{n}\right)

Własność #2

Zauważmy, że jeśli do BST wstawimy nn elementów w uporządkowanej kolejności to jego wysokość będzie wynosić h=nh=n.

Twierdzenie #1

E(wysokosˊci BST o n węzłach)=O(logn)\mathrm{E}(\text{wysokości BST o }n\text{ węzłach}) = O(\log n) zakładając, że kolejność wstawianych elementów do drzewa jest zadana przez losową permutację.

D-d Twierdzenia #1

  1. Zamiast analizować zmienną losową wysokości drzewa HnH_n, analizujemy zmienną Yn=2HnY_n = 2^{H_n}.
  2. Wykorzystując indukcję dowodzimy, że E(Yn)=O(n3)\mathrm{E}(Y_n) = O(n^3)
  3. Wykorzystując nierówność Jensena oraz powyżej udowodnioną równość na wartości oczekiwanej YnY_n otrzymujemy E(Hn)3log(n)+O(1)\mathrm{E}(H_n) \le 3\log(n) + O(1). Luc Devroye w 1986r pokazał, że E(Hn)=2.9882log(n)+o(logn)\mathrm{E}(H_n) = 2.9882\dots\log(n) + o(\log n)

Sources

Więcej informacji na temat BST można znaleźć tu (Chapter 12) oraz tutaj.