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

Podobne dokumenty
Wstęp do programowania. Drzewa. Piotr Chrząstowski-Wachtel

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

Porządek symetryczny: right(x)

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

Wstęp do programowania. Listy. Piotr Chrząstowski-Wachtel

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:

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

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

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

Drzewa poszukiwań binarnych

Listy, kolejki, stosy

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

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

Sortowanie bąbelkowe

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

ALGORYTMY I STRUKTURY DANYCH

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

ALGORYTMY I STRUKTURY DANYCH

Algorytmy i struktury danych. wykład 5

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

Drzewa podstawowe poj

Matematyka dyskretna - 7.Drzewa

Algorytmy i struktury danych

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

Drzewa czerwono-czarne.

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

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

Podstawy Informatyki. Metody dostępu do danych

Metody Kompilacji Wykład 3

Algorytmy i Struktury Danych, 9. ćwiczenia

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

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

Drzewa AVL definicje

Wstęp do programowania. Procedury i funkcje. Piotr Chrząstowski-Wachtel

Struktury Danych i Złożoność Obliczeniowa

Drzewa poszukiwań binarnych

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

Poprawność semantyczna

Sortowanie. Kolejki priorytetowe i algorytm Heapsort Dynamiczny problem sortowania:

7a. Teoria drzew - kodowanie i dekodowanie

Drzewo binarne BST. LABORKA Piotr Ciskowski

Drzewa wyszukiwań binarnych (BST)

Wykład 3. Drzewa czerwono-czarne

Wstęp do programowania

Algorytmy i Struktury Danych

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 X. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2016 Janusz Słupik

Egzaminy i inne zadania. Semestr II.

Algorytmy i Struktury Danych

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

Algorytmy i Struktury Danych

Grafy (3): drzewa. Wykłady z matematyki dyskretnej dla informatyków i teleinformatyków. UTP Bydgoszcz

Algorytmy i str ruktury danych. Metody algorytmiczne. Bartman Jacek

WSTĘP DO INFORMATYKI. Drzewa i struktury drzewiaste

ALGORYTMY I STRUKTURY DANYCH

Metody Kompilacji Wykład 7 Analiza Syntaktyczna

Informatyka 1. Wyrażenia i instrukcje, złożoność obliczeniowa

PODSTAWY INFORMATYKI wykład 6.

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

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

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

Dynamiczne struktury danych

Struktury danych: stos, kolejka, lista, drzewo

Kompresja danych Streszczenie Studia Dzienne Wykład 10,

Podstawy Informatyki. Wykład 6. Struktury danych

Algorytmy i Struktury Danych.

DIAGRAMY SYNTAKTYCZNE JĘZYKA TURBO PASCAL 6.0

Przykładowe B+ drzewo

Wstęp do programowania. Dziel i rządź. Piotr Chrząstowski-Wachtel

Wstęp do Programowania potok funkcyjny

Podstawowe algorytmy i ich implementacje w C. Wykład 9

Obliczenia na stosie. Wykład 9. Obliczenia na stosie. J. Cichoń, P. Kobylański Wstęp do Informatyki i Programowania 266 / 303

Lista liniowa dwukierunkowa

Programowanie obiektowe i C++ dla matematyków

Abstrakcyjne struktury danych w praktyce

E: Rekonstrukcja ewolucji. Algorytmy filogenetyczne

PoniŜej znajdują się pytania z egzaminów zawodowych teoretycznych. Jest to materiał poglądowy.

Algorytmy i struktury danych

Wstęp do programowania. Zastosowania stosów i kolejek. Piotr Chrząstowski-Wachtel

Programowanie strukturalne. Opis ogólny programu w Turbo Pascalu

Algorytmy i struktury danych. Co dziś? Tytułem przypomnienia metoda dziel i zwyciężaj. Wykład VIII Elementarne techniki algorytmiczne

Teoretyczne podstawy informatyki

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

REKURENCJA W JĘZYKU HASKELL. Autor: Walczak Michał

Algorytmiczna teoria grafów

Teoretyczne podstawy informatyki

Wykład 2. Poprawność algorytmów

Analiza algorytmów zadania podstawowe

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

Co to są drzewa decyzji

Wykład 14. Środowisko przetwarzania

Słowem wstępu. Część rodziny języków XSL. Standard: W3C XSLT razem XPath 1.0 XSLT Trwają prace nad XSLT 3.0

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

Algorytmy i struktury danych

Algorytmy i struktury danych

operacje porównania, a jeśli jest to konieczne ze względu na złe uporządkowanie porównywanych liczb zmieniamy ich kolejność, czyli przestawiamy je.

Wykład 6_1 Abstrakcyjne typy danych stos Realizacja tablicowa i za pomocą rekurencyjnych typów danych

TEORETYCZNE PODSTAWY INFORMATYKI

Metody teorii gier. ALP520 - Wykład z Algorytmów Probabilistycznych p.2

Dynamiczne drzewa. Marian M. Kędzierski. 26 listopada Wstęp Euler-Tour Trees Dynamiczna spójność Algorytm Dinica Link-Cut Trees

Transkrypt:

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

Drzewa wyszukiwań Drzewa często służą do przechowywania informacji. Jeśli uda sie nam stworzyć drzewo o niewielkiej wysokości i strukturze pozwalającej w każdym węźle określić, czy iść w lewo czy w prawo w poszukiwaniu jakiejś danej, to dostęp do niej będzie szybki. Takie warunki spełniają drzewa binarnych wyszukiwań (BST: Binary Search Trees) 2

Drzewa binarnych wyszukiwań W drzewach binarnych wyszukiwań przechowujemy dane ze zbioru liniowo uporządkowanego (A,<). Przestrzegamy następujących zasad: Każdą wartość reprezentujemy w drzewie co najwyżej raz, Na lewo od każdego węzła są podwieszone wyłącznie wartości mniejsze od niego, a na prawo większe. 3

Drzewa binarnych wyszukiwań Przy tak określonych zasadach wiemy, jak szukać danej wartości w drzewie: Albo drzewo jest puste i wtedy jej nie ma Albo drzewo jest niepuste i wtedy: albo wartość jest w korzeniu albo wartość jest mniejsza od tej w korzeniu, więc szukamy jej w lewym poddrzewie albo wartość jest większa od tej w korzeniu, więc szukamy jej w prawym poddrzewie 4

Wyszukiwanie wartości w drzewie zwykłym function jest(x:typ; d:drzewo):boolean; begin if d=nil then jest := false else if d^.w=x then jest := true else jest := jest(x,d^.lsyn) or jest(x,d^.psyn) {leniwie} {Koszt O(n)} 5

Wyszukiwanie wartości w drzewie BST function jest(x:typ; d:drzewo):boolean; begin if d=nil then jest := false else if d^.w=x then jest := true else if x<d^.w then jest := jest(x,d^.lsyn) else jest := jest(x,d^.psyn) {Koszt O(h)} 6

Wstawianie wartości do drzewa BST procedure wstaw(x:typ; var d:drzewo); begin if d=nil then begin new(d); d^.w:=x; d^.lsyn:=nil; d^.psyn:=nil; end else if x<d^.w then wstaw(x,d^.lsyn) else if x>d^.w then wstaw(x,d^.psyn) {Gdy x jest już w drzewie, to go 7 ignorujemy! Koszt całości O(h)}

Usuwanie wartości z drzewa BST Usuwanie wartości z drzewa BST jest nieco trudniejsze. Brak po danej wartości trzeba uzupełnić jednym z dwóch elementów: albo największym z lewego poddrzewa albo najmnijeszym z prawego. Szczegóły na ASD. Ciekawe jest pytanie o to, jaka będzie średnia głębokość węzła (albo średnia wysokość drzewa) przy budowaniu drzewa BST poprzez losowe wkładanie (i ewentualne wyjmowanie) kolejnych wartości. 8

Twierdzenie o infiksie w BST Wartości drzewa BST wypisane w obiegu infiksowym sa posortowane rosnąco. Dowód: indukcja ze wzgledu na liczbę węzłów drzewa: dla drzewa pustego OK, bo pusty ciąg jest posortowany dla drzewa niepustego mamy korzeń z podwieszonymi dwoma poddrzewami o mniejszej liczbie węzłów stosuje się więc do nich założenie indukcyjne. Zatem wartości lewego poddrzewa, wypisywane są jako pierwsze rosnąco na mocy założenia indukcyjnego potem idzie wartość z korzenia jeszcze większa (def. BST), a na końcu rosnące wartości z prawego poddrzewa. 9

Techniki przydatne przy przetwarzaniu drzew Pokażemy teraz na przykładzie obliczania wysokości drzewa dwie techniki specyficzne dla drzew. Wysokość drzewa możemy zdefiniować rekurencyjnie tak: h(nil) = -1 h(d) = max(h(d^.lsyn),h(d^.psyn)) + 1 Ta definicja przekłada się natychmiast na funkcję rekurencyjną: 10

Wysokość drzewa wprost xz definicji function h(d:drzewo):integer; begin if d=nil then h := -1 else h:=max(h(d^.lsyn),h(d^.psyn))+1 {Koszt O(n)} Mamy tu oczywiście ukryty obieg postfiksowy: nie możemy poznac wysokości ojca, zanim nie poznamy wysokości jego synów. 11

Metoda spaceru Jest to metoda, za pomocą której przechodzimy drzewo stosownym (dowolnym) obiegiem i zauważamy pewne fakty, które nas interesują zapamiętując ich efekty na zewnętrznej zmiennej. W przypadku wysokości interesuje nas największa głębokość, więc przechodząc drzewo dowolnym obiegiem po prostu za każdym razem, gdy wejdziemy do nowego węzła, aktualizujemy głębokośc, na której sie znajdujemy (aktg) i sprawdzamy, czy nie pobiliśmy rekordu (maxg). 12

Wysokość drzewa spacerem - prefiksowo function wysokośćspacerowa(d:drzewo):integer; var aktg,maxg:integer; procedure spacer(d:drzewo); begin if d<>nil then begin {spacer} aktg:=aktg+1; if aktg>maxg then maxg:=aktg; spacer(d^.lsyn); spacer(d^.psyn); aktg:=aktg-1; {Bardzo ważne!!!} {spacer} begin {WysokośćSpacerowa} aktg:=-1; maxg:=-1; spacer(d); WysokośćSpacerowa:=maxg 13

Wysokość drzewa spacerem - infiksowo function wysokośćspacerowa(d:drzewo):integer; var aktg,maxg:integer; procedure spacer(d:drzewo); begin if d<>nil then begin {spacer} aktg:=aktg+1; spacer(d^.lsyn); if aktg>maxg then maxg:=aktg; { infiksowo } spacer(d^.psyn); aktg:=aktg-1; {Bardzo ważne!!!} {spacer} begin {WysokośćSpacerowa} aktg:=-1; maxg:=-1; spacer(d); WysokośćSpacerowa:=maxg 14

Wysokość drzewa spacerem - postfiksowo function wysokośćspacerowa(d:drzewo):integer; var aktg,maxg:integer; procedure spacer(d:drzewo); begin if d<>nil then begin {spacer} aktg:=aktg+1; spacer(d^.lsyn); spacer(d^.psyn); if aktg>maxg then maxg:=aktg; { postfiksowo } aktg:=aktg-1; {Bardzo ważne!!!} {spacer} begin {WysokośćSpacerowa} aktg:=-1; maxg:=-1; spacer(d); WysokośćSpacerowa:=maxg 15

Przekazywanie parametrów w obiegu prefiksowym procedure Nadsumuj(d:drzewo); procedure DodajGore(d:drzewo; k:integer); {Dosumowuje wartość parametru k do węzła d i nową wartość przekazuje rekurencyjnie obu synom.} begin if d<> nil then begin d^.w:=d^.w+k; DodajGore(d^.lsyn,d^.w); DodajGore(d^.psyn,d^.w); begin {Nadsumuj} DodajGore(d,0) 16

Przekazywanie parametrów w obiegu postfiksowym procedure Podsumuj(d:drzewo); var dowol:integer; procedure DodajDół(d:drzewo; var k:integer); var zdolu:integer; begin if d=nil then k:=0 {To przypisanie jest konieczne!} else begin DodajDol(d^.lsyn, zdolu); d^.w:=d^.w+zdolu; DodajDol(d^.psyn, zdolu); d^.w:=d^.w+zdolu; k:=d^.w end {else}; {DodajDół} begin {Podsumuj} DodajDol(d,dowol) {Można było uniknąć dowola wstawiając tu np. d^.w, ale to by zaciemniło kod} 17

Dobre rady dotyczące stylu programowania Procedura udostępniana użytkownikowi powinna mieć tyle parametrów, ile jest to konieczne z punktu widzenia specyfikacji zadania. Wszelkie nadmiarowe parametry ułatwiające zaprogramowanie są wyrazem niechlujstwa. Złą praktyką programistyczną jest nieumieszczanie istotnych parametrów w nagłówku i korzystanie ze zmiennych globalnych. Rekurencja i iteracja niezbyt się lubią nawzajem. Najczęściej dobrze jest zdecydować się na jedną z nich. 18

Dobre rady dotyczące stylu programowania W procedurach rekurencyjnych dotyczących drzew zawsze sprawdzamy na początku, czy argument nie jest nilem. Przy przekazywaniu informacji od korzenia w dół używamy najczęściej porządku prefiksowego, a informację przekazujmy przez wartość Przy przekazywaniu informacji z dołu drzewa do góry używamy najczęściej porządku postfiksowego i przekazujemy ją albo przez parametry wołane przez zmienną albo za pomocą wywołania funkcji. 19

Podsumuj w obiegu postfiksowym z funkcją procedure Podsumuj(d:drzewo); var dowol:integer; function SumaPotomków(d:drzewo):Integer; begin if d=nil then SumaPotomków:=0 { koniecznie!} else begin d^.w := SumaPotomków(d^.lsyn)+SumaPotomków(d^.psyn) +d^.w; SumaPotomków:=d^.w end {else}; {DodajDół} begin {Podsumuj} dowol:=sumapotomków(d) {lub d^.w:=sumapotomków(d)} 20

Drzewa ogólne Jeśli drzewoma stopień większy niz dwa, to możemy je implementować w następujący sposób: w kazdym węźle przechowujemy poza wartością w:typ dwa wskaźniki: do pierwszego syna z lewej oraz do listy braci. 21

Drzewa ogólne type drzewoog = ^węzeł; węzeł = record w : typ; lsyn,brat : drzewoog var 5 d 22

Drzewa ogólne Jeśli drzewo ma stopień większy niz dwa, to możemy je implementować w następujący sposób: w kazdym węźle przechowujemy poza wartością w:typ dwa wskaźniki: do pierwszego syna z lewej oraz do listy braci. 23

Drzewa ogólne Widzimy, że różnica tak naprawdę polega na innej interpretacji takich samych danych. W rzeczywistości ta interpretacja oznacza, że w korzeniu pole brat jest zawsze puste.... chyba że nie jest puste i wtedy w naturalny sposób mamy reprezentację lasu ważnego uogólnienia drzew (drzewo wtedy, to las z jednym elementem). Procedury obiegu drzew ogólnych są analogiczne do takich procedur dla drzew binarnych 24

Drzewa ogólne - obiegi Jeśli chodzi o obiegi prefiksowy i postfiksowy, to odpowiedniość jest jednoznaczna Obiegów infiksowych można sobie wyobrazić więcej tyle ile jest wynosi stopień drzewa minus 1. W zasadzie nie używa sie obiegów infiksowych w przypadku drzew ogólnych 25

Liczymy liczbę liści w drzewie ogólnym function LiczbaLiści(d: drzewoog): integer; var lewo, prawo: integer; begin if d = nil then LiczbaLiści:=0 else if d^.lsyn=nil then LiczbaLiści:=1 else LiczbaLisci := LiczbaLiści(d^.lsyn) + Liczbaliści(d^.brat); end 26

Liczymy liczbę liści w drzewie binarnym function LiczbaLiści(d: drzewo ): integer; var lewo, prawo: integer; begin if d = nil then LiczbaLiści:=0 else if d^.lsyn=d^.psyn then LiczbaLiści:=1 else LiczbaLiści := LiczbaLiści(d^.lsyn) + Liczbaliści(d^.psyn); end 27

Przykład liczenie wysokości drzewa ogólnego function h(d:drzewoog):integer; begin if d=nil then h := -1 else h:=max(h(d^.lsyn)+1,h(d^.brat)) 28

Przykład liczenie wysokości drzewa bin. - przypomnienie function h(d:drzewo ):Integer; begin if d=nil then h := -1 else h:=max(h(d^.lsyn),h(d^.psyn))+1 29