Drzewa poszukiwań binarnych

Podobne dokumenty
Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych. Algorytmy i struktury danych Laboratorium 7. 2 Drzewa poszukiwań binarnych

Porządek symetryczny: right(x)

Listy, kolejki, stosy

Drzewa wyszukiwań binarnych (BST)

Wykład 6. Drzewa poszukiwań binarnych (BST)

Wykład 2. Drzewa poszukiwań binarnych (BST)

Wysokość drzewa Głębokość węzła

Drzewa BST i AVL. Drzewa poszukiwań binarnych (BST)

ZASADY PROGRAMOWANIA KOMPUTERÓW ZAP zima 2014/2015. Drzewa BST c.d., równoważenie drzew, kopce.

Drzewo. Drzewo uporządkowane ma ponumerowanych (oznaczonych) następników. Drzewo uporządkowane składa się z węzłów, które zawierają następujące pola:

Wyszukiwanie w BST Minimalny i maksymalny klucz. Wyszukiwanie w BST Minimalny klucz. Wyszukiwanie w BST - minimalny klucz Wersja rekurencyjna

Drzewa czerwono-czarne.

. Podstawy Programowania 2. Drzewa bst - część druga. Arkadiusz Chrobot. 12 maja 2019

Każdy węzeł w drzewie posiada 3 pola: klucz, adres prawego potomka i adres lewego potomka. Pola zawierające adresy mogą być puste.

Wykład 2. Drzewa zbalansowane AVL i 2-3-4

Drzewa poszukiwań binarnych

Przypomnij sobie krótki wstęp do teorii grafów przedstawiony na początku semestru.

Algorytmy i struktury danych. wykład 5

Podstawy programowania 2. Temat: Drzewa binarne. Przygotował: mgr inż. Tomasz Michno

ALGORYTMY I STRUKTURY DANYCH

WSTĘP DO INFORMATYKI. Drzewa i struktury drzewiaste

Drzewa binarne. Drzewo binarne to dowolny obiekt powstały zgodnie z regułami: jest drzewem binarnym Jeśli T 0. jest drzewem binarnym Np.

Podstawy Informatyki. Metody dostępu do danych

Wykład 8. Drzewa AVL i 2-3-4

ALGORYTMY I STRUKTURY DANYCH

Wykład X. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2016 Janusz Słupik

< K (2) = ( Adams, John ), P (2) = adres bloku 2 > < K (1) = ( Aaron, Ed ), P (1) = adres bloku 1 >

Algorytmy i Struktury Danych

Tadeusz Pankowski

Dynamiczny przydział pamięci w języku C. Dynamiczne struktury danych. dr inż. Jarosław Forenc. Metoda 1 (wektor N M-elementowy)

Wstęp do programowania. Drzewa podstawowe techniki. Piotr Chrząstowski-Wachtel

Algorytmy i Struktury Danych, 9. ćwiczenia

Algorytmy i struktury danych

Lista liniowa dwukierunkowa

Drzewo binarne BST. LABORKA Piotr Ciskowski

Algorytmy i struktury danych. Drzewa: BST, kopce. Letnie Warsztaty Matematyczno-Informatyczne

Teoretyczne podstawy informatyki

Kolejka priorytetowa. Często rozważa się kolejki priorytetowe, w których poszukuje się elementu minimalnego zamiast maksymalnego.

Poprawność semantyczna

Struktury Danych i Złożoność Obliczeniowa

Struktury danych: stos, kolejka, lista, drzewo

Algorytmy i. Wykład 5: Drzewa. Dr inż. Paweł Kasprowski

Wykład 3. Złożoność i realizowalność algorytmów Elementarne struktury danych: stosy, kolejki, listy

prowadzący dr ADRIAN HORZYK /~horzyk tel.: Konsultacje paw. D-13/325

Wykład 3. Drzewa czerwono-czarne

Teoretyczne podstawy informatyki

Wstęp do programowania

Algorytmy i Struktury Danych

. Podstawy Programowania 2. Drzewa bst - część pierwsza. Arkadiusz Chrobot. 22 maja 2016

Algorytmy i Struktury Danych

PLAN WYKŁADU BAZY DANYCH INDEKSY - DEFINICJE. Indeksy jednopoziomowe Indeksy wielopoziomowe Indeksy z użyciem B-drzew i B + -drzew

Przykładowe B+ drzewo

Sortowanie bąbelkowe

Algorytmy i Struktury Danych.

Plan wykładu. Klucz wyszukiwania. Pojęcie indeksu BAZY DANYCH. Pojęcie indeksu - rodzaje indeksów Metody implementacji indeksów.

Ogólne wiadomości o grafach

Algorytmy i złożoności. Wykład 3. Listy jednokierunkowe

Programowanie w VB Proste algorytmy sortowania

UNIWERSYTET GDAŃSKI MATERIAŁY DYDAKTYCZNE DO PRZEDMIOTU MATEMATYKA DYSKRETNA. pod redakcją: Hanna Furmańczyk Karol Horodecki Paweł Żyliński

Zadanie 1 Przygotuj algorytm programu - sortowanie przez wstawianie.

AiSD zadanie drugie. Gliwiński Jarosław Marek Kruczyński Konrad Marek Grupa dziekańska I5. 10 kwietnia 2008

Programowanie obiektowe

Koszt zamortyzowany. Potencjał - Fundusz Ubezpieczeń Kosztów Algorytmicznych

Matematyka dyskretna - 7.Drzewa

Wstęp do programowania

Podstawy Informatyki. Wykład 6. Struktury danych

Sortowanie. Kolejki priorytetowe i algorytm Heapsort Dynamiczny problem sortowania:

dr inż. Paweł Myszkowski Wykład nr 11 ( )

Bazy danych. Andrzej Łachwa, UJ, /15

Sortowanie. Bartman Jacek Algorytmy i struktury

Sortowanie - wybrane algorytmy

Instrukcje dla zawodników

EGZAMIN - Wersja A. ALGORYTMY I STRUKTURY DANYCH Lisek89 opracowanie kartki od Pani dr E. Koszelew

Drzewa podstawowe poj

Ogólne wiadomości o drzewach

ALGORYTMY I STRUKTURY DANYCH

Algorytmy i Struktury Danych.

OSTASZEWSKI Paweł (55566) PAWLICKI Piotr (55567) Algorytmy i Struktury Danych PIŁA

Programowanie obiektowe

WYKŁAD 10. Zmienne o złożonej budowie Statyczne i dynamiczne struktury danych: lista, kolejka, stos, drzewo. Programy: c5_1.c, c5_2, c5_3, c5_4, c5_5

BAZY DANYCH. Microsoft Access. Adrian Horzyk OPTYMALIZACJA BAZY DANYCH I TWORZENIE INDEKSÓW. Akademia Górniczo-Hutnicza

PODSTAWY INFORMATYKI wykład 6.

BAZY DANYCH. Microsoft Access. Adrian Horzyk OPTYMALIZACJA BAZY DANYCH I TWORZENIE INDEKSÓW. Akademia Górniczo-Hutnicza

Algorytmy zachłanne. dr inż. Urszula Gałązka

Algorytmy i struktury danych

Algorytmy i struktury danych Struktury danych - drzewa IS/IO, WIMiIP

Algorytmy i struktury danych. Wykład 4 Tablice nieporządkowane i uporządkowane

Distributed Hash Tables i ich zastosowania

liniowa - elementy następują jeden za drugim. Graficznie możemy przedstawić to tak:

Podstawy Informatyki Metody dostępu do danych

Dynamiczne struktury danych

Algorytmy i struktury danych

XML i nowoczesne technologie zarządzania treścią 2007/08

Definicja pliku kratowego

Wykład 7 Abstrakcyjne typy danych słownik (lista symboli)

Wykład 5. Sortowanie w czasie liniowologarytmicznym

STRUKTURY DANYCH I ZŁOŻONOŚĆ OBLICZENIOWA STRUKTURY DANYCH I ZŁOŻONOŚĆ OBLICZENIOWA. Część 3. Drzewa Przeszukiwanie drzew

Algorytmy sortujące i wyszukujące

Techniki wyszukiwania danych haszowanie

Zastosowania drzew binarnych

Transkrypt:

1 Cel ćwiczenia Algorytmy i struktury danych Instytut Sterowania i Systemów Informatycznych Wydział Elektrotechniki, Informatyki i Telekomunikacji Uniwersytet ielonogórski Drzewa poszukiwań binarnych Ćwiczenie ma na celu zapoznanie studentów z drzewami poszukiwań binarnych BST (ang. Binary Search Trees). W szczególności omówione zostaną podstawowe operacje możliwe do wykonania na drzewach BST tj. przeszukiwanie, szukanie minimum i maksimum, wstawianie oraz usuwanie elementów drzewa. 2 Drzewa poszukiwań binarnych Do reprezentacji drzew BST można wykorzystać różne struktury tworzone w oparciu o zmienne dynamiczne. Podstawowe operacje na drzewach poszukiwań binarnych wymagają czasu proporcjonalnego do wysokości drzewa. W pełnym (tzw. zrównoważonym) drzewie binarnym o n węzłach takie operacje działają w najgorszym przypadku w czasie O(log n). Jeśli jednak drzewo składa się z jednej gałęzi o długości n, to te same operacje wymagają w pesymistycznym przypadku czasu O(n). Drzewo binarne spełnia następującą charakterystyczną własność, pozwalającą na szybkie wyszukiwanie jego elementów: Niech x będzie węzłem drzewa BST. Jeśli y jest węzłem znajdującym się w lewym poddrzewie węzła x, to klucz[y] klucz[x]. Jeśli y jest węzłem znajdującym się w prawym poddrzewie węzła x, to klucz[x] klucz[y]. Inaczej mówiąc, dla każdego węzła x klucze znajdujące się w jego lewym poddrzewie są nie większe niż klucz[x], a klucze w jego prawym poddrzewie są nie mniejsze niż klucz[x] (zobacz Rys. 1). 3 1 8 Rys. 1: Przykładowe drzewo BST W korzeniu drzewa znajduje się klucz, klucze 1, 3 oraz w jego lewym poddrzewie są nie większe niż, a klucze oraz 8 znajdujące się w jego prawym poddrzewie są nie mniejsze niż. Ta sama własność jest spełniona w każdym węźle drzewa. Na przykład klucz 3 na rysunku jest nie mniejszy niż klucz 1 znajdujący się w jego lewym poddrzewie oraz nie większy niż klucz znajdujący się w jego prawym poddrzewie. Ten sam zbiór wartości może być przedstawiony za pomocą wielu różnych drzew BST. Pesymistyczny czas działania większości operacji na drzewach BST jest proporcjonalny do wysokości drzewa. Na Rys. 1 przedstawiono drzewo BST o wysokości 2 składające się z węzłów. Nieco mniej efektywne drzewo BST zawierające te same klucze może mieć wysokość 4 (zobacz Rys. 2). Wysokość obydwu drzew jest różna pomimo, iż są

Drzewa poszukiwań binarnych 2 zbudowane z identycznych danych. Wysokość drzewa zależy od kolejności danych. Drzewo BST można zrealizować za pomocą struktury danych z dowiązaniami (np. listy), w której każdy węzeł jest obiektem. Oprócz pola klucz każdy węzeł zawiera pola lewy, prawy oraz rodzic, które wskazują odpowiednio na jego lewego syna, prawego syna oraz ojca. Jeśli węzeł nie ma następnika albo poprzednika, to odpowiednie pole ma wartość NULL. Węzeł w korzeniu drzewa jest jedynym węzłem, którego pole wskazujące na ojca ma wartość NULL. 1 3 8 Rys. 2: Przykładowe drzewo BST o wysokości 4 3 Przechodzenie drzewa BST Własność drzewa BST umożliwia wypisanie wszystkich znajdujących się w nim kluczy w sposób uporządkowany za pomocą prostego algorytmu rekurencyjnego zwanego przechodzeniem drzewa metodą INORDER. Nazwa tego algorytmu wynika stąd, że klucz korzenia poddrzewa zostaje wypisany między wartościami z jego lewego poddrzewa a wartościami z jego prawego poddrzewa. Podobnie algorytm przechodzenia drzewa metodą PREORDER wypisuje klucz korzenia przed wypisaniem wartości znajdujących się w obu poddrzewach, a algorytm przechodzenia drzewa metodą POSTORDER wypisuje klucz korzenia po wypisaniu wartości znajdujących się w poddrzewach. 4 Wyszukiwanie węzła w drzewie BST Do wyszukiwania w drzewie BST węzła, który zawiera dany klucz, można użyć następującej procedury. Mając dany wskaźnik do korzenia drzewa oraz klucz k, procedura SUKAJ wyznacza wskaźnik do węzła zawierającego klucz k, jeżeli taki węzeł istnieje. W przeciwnym razie daje w wyniku wartość NULL. Algorytm 1: Rekurencyjne wyszukiwanie węzła w drzewie SUKAJ(x,k) 1 if (x = NULL) lub (k = klucz[x]) 2 return x 3 if k < klucz[x] 4 return SUKAJ(lewy[x],k) else return SUKAJ(prawy[x],k)

Drzewa poszukiwań binarnych 3 18 3 1 2 4 13 9 Rys. 3: Wyszukiwanie węzła w drzewie BST Procedura ta rozpoczyna wyszukiwanie w korzeniu i schodzi po ścieżce w dół drzewa (zobacz Rys. 3). Dla każdego węzła x, który napotka, porównuje klucz k z wartością klucz[x]. Jeśli te wartości są równe, to wyszukiwanie zostaje przerwane. Jeśli k < klucz[x], to dalsze wyszukiwanie przebiega już tylko w lewym poddrzewie węzła x, ponieważ z własności drzewa BST wynika, że k nie może znajdować się w prawym poddrzewie. Analogicznie, jeśli k > klucz[x], to wyszukiwanie zostaje ograniczone do prawego poddrzewa. Liczba węzłów odwiedzonych podczas rekurencyjnego zejścia z korzenia drzewa, a zarazem czas działania procedury SUKAJ wynosi O(h), gdzie h jest wysokością drzewa. Przedstawioną procedurę można zapisać iteracyjnie przez rozwinięcie rekursji w pętlę while. Na większości komputerów ta druga wersja jest efektywniejsza. Algorytm 2: Iteracyjne wyszukiwanie węzła w drzewie SUKAJ(x,k) 1 while (x <> NULL) i (k <> klucz[x]) 2 if k < klucz[x] 3 x = lewy[x] 4 else x = prawy[x] return x Wyszukanie klucza 13 w drzewie na Rys. 3 wymaga przejścia po ścieżce ---13. Najmniejszym kluczem w drzewie jest 2. Aby do niego dotrzeć, należy podążać zawsze według wskaźników lewy, począwszy od korzenia. Największy klucz (tutaj ) w drzewie można znaleźć, podążając od korzenia według wskaźników prawy. Następnikiem węzła o kluczu jest węzeł o kluczu 1, ponieważ jest to najmniejszy klucz w prawym poddrzewie węzła. Węzeł o kluczu 13 nie ma prawego poddrzewa, jego następnikiem jest więc najniższy przodek, którego lewy syn jest również przodkiem 13. Następnikiem węzła o kluczu 13 jest więc węzeł o kluczu.

Drzewa poszukiwań binarnych 4 Wyszukiwanie minimalnego i maksymalnego elementu w drzewie BST Element w drzewie BST o najmniejszym kluczu można łatwo odszukać podążając według wskaźników lewy, począwszy od korzenia, aż napotkamy N U LL (zobacz Rys. 3). Następująca procedura wyznacza wskaźnik do minimalnego elementu poddrzewa o korzeniu w węźle x: Algorytm 3: Wyszukiwanie minimalnego elementu drzewa MINIMUM(x) 1 while (lewy[x] <> NULL) 2 x = lewy[x] 3 return x Poprawność powyższej procedury wynika z własności drzewa BST. Jeśli węzeł x nie ma lewego poddrzewa, to najmniejszym elementem w poddrzewie o korzeniu x jest klucz[x], ponieważ każdy klucz w jego prawym poddrzewie jest co najmniej tak duży jak klucz[x]. Jeśli natomiast węzeł x ma lewe poddrzewo, to najmniejszy klucz w poddrzewie o korzeniu x znajduje się na pewno w poddrzewie o korzeniu lewy[x], bo każdy węzeł w lewym poddrzewie jest nie większy niż klucz[x], a wszystkie klucze w prawym poddrzewie są nie mniejsze niż klucz[x]. Procedura MAKSIMUM wyszukująca maksymalny element drzewa BST jest analogiczna, różnica jest tylko taka, że przesuwamy się po wskaźnikach prawy. Algorytm 4: Wyszukiwanie maksymalnego elementu drzewa MAKSIMUM(x) 1 while (prawy[x] <> NULL) 2 x = prawy[x] 3 return x Obie procedury działają na drzewie o wysokości h w czasie O(h), ponieważ przechodzą tylko po ścieżce w dół drzewa. Wstawianie węzła do drzewa BST Operacja wstawiania elementu zmienia zbiór dynamiczny reprezentowany przez drzewo BST. Ta zmiana wymaga przeorganizowania struktury drzewa, ale w taki sposób, aby została zachowana własność drzewa BST. Modyfikacja drzewa niezbędna przy wstawieniu nowego elementu jest dość łatwa, gorzej jest przy usuwaniu elementu. Nową wartość v można wstawić do drzewa poszukiwań binarnych T za pomocą procedury WSTAW. Do procedury przekazujemy jako argument węzeł z, w którym klucz[z] = v, lewy[z] = NULL oraz prawy[z] = NULL. W wyniku wykonania procedury drzewo T oraz niektóre pola z są modyfikowane w sposób, który odpowiada wstawieniu z we właściwe miejsce w drzewie.

Drzewa poszukiwań binarnych 12 18 2 9 19 13 1 Rys. 4: Wstawianie węzła z kluczem 13 do drzewa BST 1 1 10 18 23 Rys. : Usuwanie węzła z z drzewa BST przypadek 1. Algorytm : Wstawianie węzła do drzewa WSTAW(T,z) 1 y = NULL 2 x = korzen[t] 3 while (x <> NULL) 4 y = x if (klucz[z] < klucz[x]) x = lewy[x] else x = prawy[x] 8 rodzic[z] = y 9 if (y = NULL) 10 korzen[t] = z 11 else if (klucz[z] < klucz[y]) 12 lewy[y] = z 13 else prawy[y] = z Na Rys. 4 przedstawiony jest sposób działania procedury WSTAW. Podobnie jak w przypadku procedur SUKAJ iteracyjnie i SUKAJ rekurencyjnie, procedura WSTAW rozpoczyna przeglądanie w korzeniu, a następnie przebiega po ścieżce w dół drzewa. Wskaźnik x przebiega po ścieżce, a zmienna y zawiera zawsze wskazanie na ojca x. Po zainicjowaniu wartości zmiennych w pętli while w wierszach 3- wskaźniki x i y są przesuwane w dół drzewa w lewo lub w prawo, w zależności od wyniku porównania klucz[z] z klucz[x], aż do chwili, w której zmienna x

Drzewa poszukiwań binarnych 1 18 23 10 13 Rys. : Usuwanie węzła z z drzewa BST przypadek 2. y 1 1 1 y Rys. : Usuwanie węzła z z drzewa BST przypadek 3. przyjmie wartość NULL. Ta właśnie wartość NULL zajmuje miejsce w drzewie, w którym należy umieścić wskaźnik na węzeł z. Wstawienie z do drzewa (tzn. wiążące się z tym przypisania właściwych wartości odpowiednim wskaźnikom) odbywa się w wierszach 8-13 procedury. Na Rys. 4 kolorowe węzły wchodzą w skład ścieżki od korzenia do miejsca, w którym węzeł zostaje wstawiony. Kolorową linią jest oznaczony wskaźnik, który zostaje utworzony w wyniku dodania elementu do drzewa. Procedura WSTAW, podobnie jak inne elementarne operacje na drzewach poszukiwań, działa na drzewie o wysokości h w czasie O(h). Usuwanie węzła z drzewa BST Argumentem procedury służącej do usuwania danego węzła z z drzewa poszukiwań binarnych jest wskaźnik do z. W procedurze tej rozpatrywane są trzy przypadki. 1. Jeśli z nie ma synów, to w jego ojcu rodzic[z] zastępujemy wskaźnik do z wartością NULL, zobacz Rys.. 2. Jeśli węzeł ma tylko jednego syna, to usuwamy z przez ustalenie wskaźnika między jego ojcem a jedynym synem, zobacz Rys.. 3. Jeśli węzeł ma dwóch synów, to usuwamy następnik y węzła z, o którym wiadomo, że nie ma lewego syna oraz zastępujemy zawartość z zawartością y, zobacz Rys.. Procedura USUN realizuje wszystkie trzy wyżej przedstawione przypadki.

Drzewa poszukiwań binarnych Algorytm : Usuwanie węzła z drzewa USUN(T,z) 1 if (lewy[z] = NULL) lub (prawy[z] = NULL) 2 y = z 3 else y = NASTEPNIK(z) 4 if (lewy[y] <> NULL) x = lewy[y] else x = prawy[y] if (x <> NULL) 8 rodzic[x] = rodzic[y] 9 if (rodzic[y] = NULL) 10 korzen[t] = x 11 else if y = lewy[rodzic[y]] 12 lewy[rodzic[y]] = x 13 else prawy[rodzic[y]] = x 14 if y <> z klucz[z] = klucz[y] 1 // Jeśli y ma inne pola, to je // także należy skopiować. 1 return y W wierszach 1-3 procedury zostaje wyznaczony węzeł y, który zostanie usunięty z drzewa. Węzeł y może być albo węzłem wejściowym z (jeśli z ma co najwyżej jednego syna), albo następnikiem z (jeśli z ma dwóch synów). Następnie w wierszach 4- zmiennej x zostaje przypisana różna od NULL wartość y albo wartość NULL, jeśli y nie ma żadnych synów. Węzeł y zostaje usunięty w wierszach -13 przez odpowiednią modyfikację wartości wskaźników rodzic[y] i x. Pełna implementacja operacji usunięcia węzła y okazuje się dość skomplikowana, ponieważ trzeba osobno rozpatrzyć szczególne przypadki: gdy x = NULL lub gdy y jest korzeniem. Wreszcie w wierszach 14-1 zawartość y zostaje przepisana do z (niszcząc poprzednią zawartość z), jeżeli następnik z został usunięty. W ostatnim wierszu do procedury wołającej zostaje przekazany węzeł y. Procedura ta może go wstawić na listę wolnych pozycji. Czas działania procedury USUN na drzewie o wysokości h wynosi O(h). 8 Ćwiczenia do wykonania 1. Wykonać ćwiczenia zawarte w protokole. 2. Na podstawie literatury dokonać analizy zastosowań drzew BST. Literatura [1] A. Drozdek Struktury danych w jezyku C, WNT 199. [2] D. E. Knuth Sztuka programowania, WNT, 02. [3] R. Sedgewick Algorytmy w C++, Wydawnictwo RM, 1999. [4] P. Wróblewski Algorytmy, struktury danych i techniki programowania, Helion, 199.