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

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

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

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

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

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:

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

Algorytmy i Struktury Danych

Teoretyczne podstawy informatyki

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

Porządek symetryczny: right(x)

Struktury danych: stos, kolejka, lista, drzewo

Teoretyczne podstawy informatyki

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

ALGORYTMY I STRUKTURY DANYCH

Algorytmy i Struktury Danych.

Algorytmy i struktury danych. wykład 5

ALGORYTMY I STRUKTURY DANYCH

Wstęp do programowania

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

Algorytmy i Struktury Danych

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

Stos LIFO Last In First Out

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

Listy, kolejki, stosy

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

Struktury Danych i Złożoność Obliczeniowa

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

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

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

Drzewa poszukiwań binarnych

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

Podstawy Informatyki. Metody dostępu do danych

Drzewa poszukiwań binarnych

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

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

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

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

Algorytmy i Struktury Danych

Algorytmy i struktury danych

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

Lista liniowa dwukierunkowa

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

Drzewa wyszukiwań binarnych (BST)

dodatkowe operacje dla kopca binarnego: typu min oraz typu max:

Programowanie obiektowe i C++ dla matematyków

Przykładowe B+ drzewo

Sortowanie bąbelkowe

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

WSTĘP DO INFORMATYKI. Drzewa i struktury drzewiaste

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

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

Abstrakcyjne struktury danych w praktyce

Metody Kompilacji Wykład 3

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

Drzewa czerwono-czarne.

Podstawy Informatyki. Wykład 6. Struktury danych

ALGORYTMY I STRUKTURY DANYCH

Ogólne wiadomości o grafach

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

Algorytmy i Struktury Danych. Co dziś? Drzewo decyzyjne. Wykład IV Sortowania cd. Elementarne struktury danych

Abstrakcyjne struktury danych - stos, lista, drzewo

Podstawowe pojęcia dotyczące drzew Podstawowe pojęcia dotyczące grafów Przykłady drzew i grafów

Wykład 8 - Drzewa i algorytmy ich przetwarzania

Algorytmy i Struktury Danych, 9. ćwiczenia

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

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

Podstawy informatyki 2. Podstawy informatyki 2. Wykład nr 2 ( ) Plan wykładu nr 2. Politechnika Białostocka. - Wydział Elektryczny

Wykład 5 Wybrane zagadnienia programowania w C++ (c.d.)

Drzewo binarne BST. LABORKA Piotr Ciskowski

Indeksy. Wprowadzenie. Indeksy jednopoziomowe indeks podstawowy indeks zgrupowany indeks wtórny. Indeksy wielopoziomowe

Typy danych. 2. Dane liczbowe 2.1. Liczby całkowite ze znakiem i bez znaku: 32768, -165, ; 2.2. Liczby rzeczywiste stało i zmienno pozycyjne:

Odwrotna Notacja Polska

Programowanie obiektowe

Algorytmy i. Wykład 3: Stosy, kolejki i listy. Dr inż. Paweł Kasprowski. FIFO First In First Out (kolejka) LIFO Last In First Out (stos)

TEORETYCZNE PODSTAWY INFORMATYKI

Definicja pliku kratowego

Podstawy informatyki 2

Tadeusz Pankowski

TEORETYCZNE PODSTAWY INFORMATYKI

Informatyka 2. Wykład nr 5 ( ) Plan wykładu nr 5. Politechnika Białostocka. - Wydział Elektryczny. Odwrotna notacja polska.

Informatyka 2. Wykład nr 5 ( ) Politechnika Białostocka. - Wydział Elektryczny. dr inŝ. Jarosław Forenc

INFORMATYKA. Podstawy programowania w języku C. (Wykład) Copyright (C) 2005 by Sergiusz Sienkowski IME Zielona Góra

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.

Programowanie obiektowe i C++ dla matematyków

Modelowanie hierarchicznych struktur w relacyjnych bazach danych

Algorytmy sortujące i wyszukujące

Programowanie obiektowe

Dynamiczny przydział pamięci (język C) Dynamiczne struktury danych. Sortowanie. Klasyfikacja algorytmów sortowania. Algorytmy sortowania

WYŻSZA SZKOŁA INFORMATYKI STOSOWANEJ I ZARZĄDZANIA

Drzewa podstawowe poj

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

Algorytmy i Struktury Danych.

Algorytmy i struktury danych

Matematyka dyskretna - 7.Drzewa

Algorytmy i Struktury Danych.

Kompresja danych Streszczenie Studia Dzienne Wykład 10,

Zofia Kruczkiewicz, Algorytmu i struktury danych, Wykład 14, 1

Dynamiczne struktury danych

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

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

Transkrypt:

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

DRZEWA (ang.: trees) Drzewo struktura danych o typie podstawowym T definiowana rekurencyjnie jako: - struktura pusta, lub - węzeł typu T ze skończoną liczbą dowiązanych rozłącznych struktur drzewiastych o typie podstawowym T (zwanych także poddrzewami). Korzeń (root) - jedyny węzeł, który nie należy do poddrzewa dowiązanego do jakiegokolwiek węzła drzewa (pod warunkiem, że drzewo nie jest strukturą pustą, ani nie jest drzewem swobodnym). Dygresja W implementacjach referencja do korzenia jest zazwyczaj wykorzystywana jednocześnie jako referencja do całej struktury. Gałąź/krawędź (branch/edge) abstrakcyjny fakt potwierdzający powiązanie dwóch węzłów drzewa. Liść/węzeł końcowy (leaf) - węzeł, do którego nie są dowiązane żadne poddrzewa. Węzeł wewnętrzny (internal node) węzeł nie będący ani korzeniem, ani liściem. Poziom (level) zbiór określający lokalizację węzła w drzewie w sposób następujący: korzeń należy do poziomu pierwszego; węzły dowiązane bezpośrednio do korzenia należą do poziomu drugiego, itd. 2 / 24

Jeżeli węzeł X na poziomie (i+1)-szym jest dowiązany bezpośrednio do węzła Y na poziomie i-tym, wówczas węzeł Y nazywamy przodkiem (rodzicem, parent) węzła X, zaś węzeł X - potomkiem (dzieckiem, child) węzła Y. Wysokość (głębokość, height, depth) drzewa maksymalny spośród poziomów wszystkich węzłów drzewa. Stopień węzła - liczba bezpośrednich potomków węzła (stopień węzła będącego liściem wynosi zero ). Stopień drzewa maksymalny spośród stopni wszystkich węzłów drzewa. Dygresja Istnieją struktury drzewiaste, dla których dopuszczalny stopień węzła jest z góry ograniczony przez pewną liczbę naturalną (tzw. drzewa wielokierunkowe stopnia n), ale istnieją również takie, w których dopuszczalna liczba węzłów potomnych nie jest określona jawnie, lecz wynika z wzajemnych relacji wszystkich węzłów w drzewie (np. drzewa dwumianowe). Długość drogi węzła X - liczba gałęzi, przez które należy przejść w drodze od korzenia do węzła X (długość drogi dla korzenia wynosi 1; długość drogi węzła X należącego do poziomu i-tego wynosi i. Długość drogi drzewa (długość drogi wewnętrznej) - suma długości dróg jego wszystkich składowych (węzłów). 3 / 24

Dla powyższego drzewa: korzeniem jest węzeł A; liśćmi są węzły C, G, I, J, K, L, N i O; pozostałe węzły są węzłami wewnętrznymi; głębokość (wysokość) drzewa wynosi 5; długość drogi dla węzła J wynosi 4; długość drogi wewnętrznej drzewa wynosi 48; E jest przodkiem I, J i K; M i N są potomkami H; stopień węzła C wynosi 0; stopień węzła M wynosi 1; stopień drzewa 3; 4 / 24

Drzewa uporządkowane (ordered trees) - drzewa, w których gałęzie każdego z węzłów są liniowo uporządkowane. Maksymalna liczba węzłów drzewa wielokierunkowego stopnia d o wysokości h wynosi: Drzewo dokładnie wyważone (perfectly balanced tree) - drzewo, którego węzły (przy ustalonej ich liczbie) zajmują najmniejszą możliwą liczbę poziomów, a ponadto liście tego drzewa znajdują się wyłącznie na ostatnim lub przedostatnim poziomie. Drzewo binarne (binary tree) drzewo wielokierunkowe, którego stopień wynosi 2. Maksymalna liczba węzłów drzewa binarnego o wysokości h wynosi: N 2 ( h ) = 1 + 2 + 2 2 + + 2 h-1 = 2 h - 1 Minimalna liczba poziomów (wysokość) drzewa binarnego zawierającego N węzłów: h log 2 (N+1) 5 / 24

UPORZĄDKOWANE DRZEWA BINARNE(ang.: ordered binary trees) Uporządkowane) drzewo binarne - skończony zbiór elementów (węzłów), który jest albo pusty, albo zawiera korzeń (węzeł) z dwoma rozłącznymi binarnymi drzewami, zwanymi lewym i prawym poddrzewem korzenia. Zazwyczaj (chociaż nie zawsze) do bezpośredniego lub pośredniego ustanawiania porządku w obrębie drzewa wykorzystywana jest wyróżniona składowa węzła, zwana kluczem (key). Struktura danych dla węzła: PASCAL: type node_rec = record key : To; left, right : node_rec; data : Ti; end; C,C++: struct node_rec eltype key; struct node_rec *left, *right; datatype data; ; 6 / 24

Przykłady sposobów uporządkowania drzew binarnych Drzewo poszukiwań binarnych (ang.: binary search tree, BST): klucz lewego potomka < klucz przodka < klucz prawego potomka Kopiec binarny zorientowany (uporządkowany ze względu) na maksimum (ang.: max. binary heap): klucz lewego potomka klucz przodka i klucz prawego potomka klucz przodka W wersji alternatywnej, zwanej kopcem binarnym zorientowanym na minimum: klucz lewego potomka klucz przodka i klucz prawego potomka klucz przodka Dla pewnych drzew binarnych uporządkowanie wynika z mechanizmów konstrukcji drzewa specyficznych dla dziedziny zastosowań (np. drzewa binarne powstające w wyniku analizy fraz kodu źródłowego sformułowanego w określonym języku programowania). 7 / 24

ODWIEDZANIE WSZYSTKICH WĘZŁÓW UPORZĄDKOWANEGO DRZEWA BINARNEGO Procedura przeszukiwania wzdłużnego scan_preorder (node) if(node NULL) P(node); scan_preorder(node left); scan_preorder(node right); return; (a + b / c) * (d - e * f) P(node) wydruk znaku * + a / b c - d * e f 8 / 24

Procedura przeszukiwania poprzecznego scan_inorder (node) if(node NULL) scan_inorder(node left); P(node); scan_inorder(node right); return; (a + b / c) * (d - e * f) a + b / c * d e * f 9 / 24

Procedura przeszukiwania wstecznego scan_postorder (node) if(node NULL) scan_postorder(node left); scan_postorder(node right); P(node); return; (a + b / c) * (d - e * f) a b c / + d e f * - * 10 / 24

DRZEWA BINARNE A ODWROTNA NOTACJA POLSKA Odwrotna Notacja Polska ONP (ang.: Reverse Polish Notation RPN) sposób beznawiasowego zapisu wyrażeń formalnych (np. wyrażeń arytmetycznych) wymyślony przez Jana Łukasiewicza (1878-1956) i często wykorzystywany do translacji wyrażeń arytmetycznych lub zdań w języku programowania wysokiego poziomu. Przykład zastosowania: translacja wyrażeń arytmetycznych Zmienne reprezentowane przez pojedyncze symbole literowe (a, b, c,, z) Nawiasy reprezentowane przez symbole ( i ) Operacje arytmetyczne reprezentowane przez symbole +,, *, /,, i Symbol Priorytet a, b, c,, z -1 ( 0 ) 1 +, 2 *, /,, (negacja) 3 (potęgowanie) 4 11 / 24

Faza pierwsza eliminacja nawiasów (algorytm) Z wyrażenia wejściowego pobierane są kolejne symbole i umieszczane w stosie wynikowym lub umieszczane i zdejmowane ze stosu pomocniczego zgodnie z następującymi regułami: - jeżeli symbolem jest litera (symbole od a do z), to umieść go w stosie wynikowym (wraz z priorytetem); - jeżeli symbolem jest (, to umieść go w stosie pomocniczym (wraz z priorytetem); - jeżeli symbolem jest ), to pobierz ze stosu pomocniczego i umieść w stosie wynikowym wszystkie kolejne elementy o priorytecie 1, po pobraniu ze stosu pomocniczego symbolu ( (o priorytecie 0) przejdź do pobrania kolejnego symbolu; - jeżeli priorytet symbolu > 1, to dopóki nie umieścisz symbolu w stosie pomocniczym (wraz z priorytetem), postępuj następująco: - jeżeli stos pomocniczy jest pusty, lub na jego szczycie znajduje się element o priorytecie niższym od priorytetu pobranego symbolu, to umieść ten symbol (wraz z priorytetem) w stosie pomocniczym; - w przeciwnym przypadku pobierz element ze stosu pomocniczego i umieść go w stosie wynikowym; - jeżeli pobrane są wszystkie symbole, to kolejno pobierz elementy ze stosu pomocniczego i umieść je w stosie wynikowym. 12 / 24

Faza pierwsza eliminacja nawiasów (przykład) Wyrażenie arytmetyczne: ( a + b / c ) * ( d - e * f ) Symbol Priorytet Symbol Priorytet / 3 + 2 ( 0 Stos pomocniczy c -1 b -1 a -1 Stos wynikowy 13 / 24

Faza pierwsza eliminacja nawiasów (przykład) Wyrażenie arytmetyczne: ( a + b / c ) * ( d - e * f ) Symbol Priorytet Symbol Priorytet + 2 / 3 / 3 + 2 * ( 03 Stos pomocniczy c -1 b -1 a -1 Stos wynikowy 14 / 24

Faza pierwsza eliminacja nawiasów (przykład) Wyrażenie arytmetyczne: ( a + b / c ) * ( d - e * f ) Symbol Priorytet Symbol Priorytet f -1 e -1 d -1 + 2 * 3-2 ( 0 * 3 Stos pomocniczy / 3 c -1 b -1 a ( -1 0 Stos pomocniczy wynikowy 15 / 24

Faza pierwsza eliminacja nawiasów (przykład) Wyrażenie arytmetyczne: ( a + b / c ) * ( d - e * f ) Symbol Priorytet Symbol Priorytet * 3-2 * 3 f -1 e -1 d -1 + 2 * 3-2 ( 0 * 3 Stos pomocniczy / 3 c -1 b -1 a -1 Stos wynikowy 16 / 24

Faza druga tworzenie uporządkowanego drzewa binarnego (algorytm) Pobierz element ze szczytu stosu wynikowego i uczyń go korzeniem drzewa oraz węzłem bieżącym. Dopóki stos wynikowy nie będzie pusty postępuj zgodnie z następującymi regułami: - pobierz element ze stosu i utwórz z niego nowy węzeł; - jeżeli węzeł bieżący nie ma prawego potomka, to uczyń nim nowy węzeł; jeżeli nowy węzeł ma priorytet > 0, to uczyń go węzłem bieżącym; - w przeciwnym przypadku (jeżeli węzeł bieżący ma już prawego potomka) uczyń nowy węzeł lewym potomkiem; jeżeli nowy węzeł ma priorytet > 0, to uczyń go węzłem bieżącym; - jeżeli węzeł bieżący ma już obu potomków, to uczyń węzłem bieżącym jego rodzica. 17 / 24

Faza druga tworzenie uporządkowanego drzewa binarnego (przykład) Czerwonym kolorem wyróżniono węzeł bieżący Symbol Priorytet * 3-2 * 3 f -1 e -1 d -1 + 2 / 3 c -1 b -1 a -1 Stos wynikowy * + d Drzewo binarne - e * f 18 / 24

19 / 24 STRUKTURY DANYCH I ZŁOŻONOŚĆ OBLICZENIOWA Obliczanie wartości wyrażenia arytmetycznego - wykorzystanie procedury przeszukiwania wstecznego (pseudokod) stack_type stack; tree_type x; //referencja do korzenia char y; //chodzi o ideę, w rzeczywistości argumenty są skojarzone przez nazwy //zmiennych z odpowiednimi wartościami liczbowymi Initialize(stack); scan_postorder(x); y pop(stack); P(tree_type *node, stack_type *stack) // char arg1, arg2, z; if (node priority < 0) push(node op, stack); else if (node op = * ) arg2 pop(stack); arg1 pop(stack); z arg1 * arg2; push(z, stack); else if (node op = + ) else if (node op = - ).

JESZCZE O PRZESZUKIWANIU DRZEWA BINARNEGO W celu uniknięcia rekurencji w funkcji przeszukiwania można posłużyć się stosem w sposób jawny: scan_preorder_with_stack(node) initialize(stack); if(node NULL) push(node, stack); while(~empty(stack)) node pop(stack); P(node); if(node right NULL) push(node right, stack); if(node left NULL) push(node left, stack); return; 20 / 24

Dla przeszukiwania poprzecznego sytuacja nieco się komplikuje : scan_inorder_with_stack (node) initialize(stack); while(node NULL) while(node NULL) if(node right NULL) push(node right, stack); push(node, stack); node node left); node pop(stack); while(~empty(stack) & (node right = NULL)) P(node); node pop(stack); P(node); if(~empty(stack)) node pop(stack); else node NULL; return; 21 / 24

DRZEWA Z ŁAŃCUCHAMI DOWIĄZAŃ (ang.: threaded trees) Element typu podstawowego: struct node_rec eltype key; BOOLEAN rthread; BOOLEAN visit_switch; struct node_rec *left, *right; datatype Ti; ; Czerwonymi łukami oznaczono prawe dowiązania (right threads). Składowa rthread = TRUE dla węzłów bez prawych potomków (oprócz skrajnego prawego węzła, który jest ostatnim odwiedzanym w trybie przeszukiwania poprzecznego); ma ona istotne znaczenie dla wyszukiwania, wstawiania i usuwania węzłów. Składowa visit_switch jest jedną z możliwych form zapobiegania powtórnym odwiedzinom w węźle w procesie przeszukiwania drzewa; przed rozpoczęciem przeszukiwania poprzecznego wszystkie węzły muszą mieć identyczną wartość tej składowej (TRUE albo FALSE). 22 / 24

Dzięki dowiązaniom przeszukiwanie poprzeczne nie odwołuje się do stosu, ale wymaga utworzenia na potrzeby przeszukiwania listy już odwiedzonych węzłów, albo innego mechanizmu zapobiegającego zapętleniom (np. dynamicznej składowej logicznej; tu: visit_switch). threaded_scan_inorder (node) // p referencja na węzeł bieżący; p node; if(p = NULL) return; //drzewo jest puste cur_switch ~ (p visit_switch); while(p NULL) while((p left NULL) & (p left visit_switch cur_switch)) p p left; P(p); p visit_switch cur_switch; p p right; return; 23 / 24

Koniec części 3 24 / 24