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.