Wstęp do informatyki Wykład 10 zob. np. N. Wirth, Algorytmy +

Transkrypt

Wstęp do informatyki Wykład 10 zob. np. N. Wirth, Algorytmy +
Wstęp do informatyki
Wykład 10
Nieliniowe struktury danych – drzewa binarne
zob. np. N. Wirth, Algorytmy + struktury danych = programy
Drzewo binarne – określenie struktury danych. Graficzna postać drzewa binarnego (przykłady):
puste – wskaźnik pusty; niepuste – wskaźnik na korzeń; węzeł lub wierzchołek drzewa to
rekord/struktura z 3 polami: klucz, lewe i prawe). Drzewo poszukiwań binarnych (ang. binary
search tree) – bst (w lewym poddrzewie klucze mniejsze lub równe a w prawym większe od klucza
w korzeniu drzewa).
Wysokość (głębokość) niepustego drzewa (drzewo o 1 węźle ma wysokość 0); poziom węzłów w
drzewie; pełne drzewo binarne
Metody przeglądania drzewa binarnego:
•preorder (korzeń, lewe, prawe)
•inorder (lewe, korzeń, prawe)
•postorder (lewe, prawe, korzeń)
Przykłady: Schemat przeglądania drzewa binarnego metodą inorder i drukowania kluczy z odwiedzanych węzłów
drzewa.
Szukanie klucza w drzewie binarnym i sortowanie kluczy z drzewa bst – złożoność tych
algorytmów.
Przyjmijmy, że dla drzewa binarnego t wartościami następujących funkcji (dla 3 pierwszych t jest
niepuste) są:
klucz(t) – klucz z węzła t; lewe(t) – lewe poddrzewo t; prawe(t) – prawe poddrzewo t;
jestPuste(t) – true, jeśli t jest drzewem pustym, w przec. przypadku false.
Przykład: Szukanie klucza e w drzewie binarnym t – funkcja jestKlucz o wartości true, jeśli e jest
w t, w przeciwnym razie false
jestKlucz (e,t) =
if jestPuste(t) then false else
if klucz(t)=e then true else
if jestKlucz(e,lewe(t)) then true else
jestKlucz(e,prawe(t))
Indukcyjny dowód poprawności funkcji rekurencyjnej jestKlucz(e,t). Indukcja względem liczby
węzłów (wierzchołków) drzewa t. (zob. L. Banachowski, A. Kreczmar, Elementy analizy
algorytmów, WNT, 1982, str. 84.)
Listowa notacja zapisu drzewa binarnego: puste – [ ], jeden węzeł-korzeń z kluczem 3: [3, [ ], [ ]]
Definicja rekurencyjna niepustego drzewa t:
t=[klucz,lewe-poddrzewo,prawe-poddrzewo].
Przykłady: drzewo t
t: 7
/
\
5
9
i jego listowa reprezentacja
t= [7, [5, [ ], [ ]], [9, [ ], [ ]] ]
Funkcje dla reprezentacji listowej niepustego drzewa binarnego t mogą mieć takie implementacje
(dla pustego t są nieokreślone):
klucz(t)=pierw(t) lewe(t)=pierw(bp(t)) prawe(t)=ost(t) jestPuste(t)=t=[ ]
Przykładowe funkcje dla listowej reprezentacji t:
Funkcja liść tworząca węzeł-liść drzewa binarnego z kluczem e liść(e)=zd(e,lista([ ],[ ]))
Funkcja tworz łącząca dwa poddrzewa binarne l i p w jedno i wstawiająca do korzenia klucz e,
czyli wynikiem jest drzewo binarne w postaci [e, l, p] twórz(e, l, p) = zd(e, lista(l, p))
Wartością funkcji wstaw(e,bst) jest drzewo bst’ powstałe po wstawieniu elementu e do drzewa bst
wstaw (e,bst)=
if jestPuste(bst) then liść(e) else
if e<=klucz(bst) then
twórz(klucz(bst),wstaw(e,lewe(bst)),prawe(bs)) else
twórz(klucz(bst),lewe(bst),wstaw(e,prawe(bst)))
Porządkowanie n elementów za pomocą binarnego drzewa poszukiwań – po utworzeniu z danych
drzewa bst, jego klucze drukuje się za pomocą metody inorder; złożoność takiego porządkowania.