Stromy. Jan Hnilica Počítačové modelování 14

Podobné dokumenty
Lineární spojový seznam (úvod do dynamických datových struktur)

Stromy. Strom: souvislý graf bez kružnic využití: počítačová grafika seznam objektů efektivní vyhledávání výpočetní stromy rozhodovací stromy

Dynamické datové struktury IV.

Prioritní fronta, halda

Dynamické datové struktury III.

Reprezentace aritmetického výrazu - binární strom reprezentující aritmetický výraz

Programování 3. hodina. RNDr. Jan Lánský, Ph.D. Katedra informatiky a matematiky Fakulta ekonomických studií Vysoká škola finanční a správní 2015

Základní datové struktury III: Stromy, haldy

Stromy, haldy, prioritní fronty

AVL stromy. pro každý uzel u stromu platí, že rozdíl mezi výškou jeho levého a pravého podstromu je nejvýše 1 stromy jsou samovyvažující

DobSort. Úvod do programování. DobSort Implementace 1/3. DobSort Implementace 2/3. DobSort - Příklad. DobSort Implementace 3/3

Intervalové stromy. Představme si, že máme posloupnost celých čísel p 0, p 1,... p N 1, se kterou budeme. 1. Změna jednoho čísla v posloupnosti.

Základní datové struktury

bfs, dfs, fronta, zásobník, prioritní fronta, halda

bfs, dfs, fronta, zásobník, prioritní fronta, halda

Dynamicky vázané metody. Pozdní vazba, virtuální metody

TGH07 - Chytré stromové datové struktury

Vyvažování a rotace v BVS, všude se předpokládá AVL strom

bin arn ı vyhled av an ı a bst Karel Hor ak, Petr Ryˇsav y 23. bˇrezna 2016 Katedra poˇ c ıtaˇ c u, FEL, ˇ CVUT

Algoritmy a datové struktury

Binární vyhledávací stromy pokročilé partie

Binární vyhledávací strom pomocí směrníků Miroslav Hostaša L06620

5 Rekurze a zásobník. Rekurzivní volání metody

TGH07 - Chytré stromové datové struktury

Adresní vyhledávání (přímý přístup, zřetězené a otevřené rozptylování, rozptylovací funkce)

Aplikovaná informatika. Podklady předmětu Aplikovaná informatika pro akademický rok 2013/2014 Radim Farana. Obsah. Strom

Náplň. v Jednoduché příklady na práci s poli v C - Vlastnosti třídění - Způsoby (algoritmy) třídění

Rekurzivní algoritmy

Základy algoritmizace c2005, 2007 Michal Krátký, Jiří Dvorský1/39

Volné stromy. Úvod do programování. Kořenové stromy a seřazené stromy. Volné stromy

Pointery II. Jan Hnilica Počítačové modelování 17

Radek Mařík

NPRG030 Programování I, 2018/19 1 / :03:07

Test prvočíselnosti. Úkol: otestovat dané číslo N, zda je prvočíslem

Algoritmy na ohodnoceném grafu

Select sort: krok 1: krok 2: krok 3: atd. celkem porovnání. výběr nejmenšího klíče z n prvků vyžaduje 1 porovnání

Binární vyhledávací stromy

ADT STROM Lukáš Foldýna

přirozený algoritmus seřadí prvky 1,3,2,8,9,7 a prvky 4,5,6 nechává Metody řazení se dělí:

a) b) c) Radek Mařík

Algoritmy výpočetní geometrie

Spojová implementace lineárních datových struktur

3 Algoritmy řazení. prvku a 1 je rovněž seřazená.

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 21.

Dynamické datové struktury I.

Dynamické datové struktury II.

Pole a kolekce. v C#, Javě a C++

Cílem kapitoly je seznámit studenta se seznamem a stromem. Jejich konstrukci, užití a základní vlastnosti.

Maturitní téma: Programovací jazyk JAVA

Algoritmizace Dynamické programování. Jiří Vyskočil, Marko Genyg-Berezovskyj 2010

B3B33ALP - Algoritmy a programování - Zkouška z předmětu B3B33ALP. Marek Boháč bohacm11

Algoritmy II. Otázky k průběžnému testu znalostí

B3B33ALP - Algoritmy a programování - Zkouška z předmětu B3B33ALP. Marek Boháč bohacm11

2 Datové struktury. Pole Seznam Zásobník Fronty FIFO Haldy a prioritní fronty Stromy Hash tabulky Slovníky

Prioritní fronta, halda (heap), řazení

Programování v C++ 1, 16. cvičení

IAJCE Přednáška č. 9. int[] pole = new int[pocet] int max = pole[0]; int id; for(int i =1; i< pole.length; i++) { // nikoli 0 if (Pole[i] > max) {

Informatika navazující magisterské studium Přijímací zkouška z informatiky 2018 varianta A

Datový typ prioritní fronta Semestrální práce z předmětu 36PT

Zdůvodněte, proč funkce n lg(n) roste alespoň stejně rychle nebo rychleji než než funkce lg(n!). Symbolem lg značíme logaritmus o základu 2.

Stromy. Karel Richta a kol. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze Karel Richta a kol.

Pokročilé haldy. prof. Ing. Pavel Tvrdík CSc. Fakulta informačních technologií České vysoké učení technické v Praze c Pavel Tvrdík, 2010

Amortizovaná složitost. Prioritní fronty, haldy (binární, d- regulární, binomiální, Fibonacciho), operace nad nimi a jejich složitost

Programování v C++, 2. cvičení

Grafové algoritmy. Programovací techniky

Grafové algoritmy. Programovací techniky

Dynamické programování. Optimální binární vyhledávací strom

vyhledávací stromové struktury

Datové struktury Úvod

Spojové struktury. Spojová struktura (linked structure):

ALGORITMIZACE 2010/03 STROMY, BINÁRNÍ STROMY VZTAH STROMŮ A REKURZE ZÁSOBNÍK IMPLEMENTUJE REKURZI PROHLEDÁVÁNÍ S NÁVRATEM (BACKTRACK)

Stromy. Jan Kybic.

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 12.

Datové struktury. alg12 1

Výhody a nevýhody jednotlivých reprezentací jsou shrnuty na konci kapitoly.

Red Black strom (Red Black Tree) Úvod do programování. Rotace. Red Black strom. Rotace. Rotace

Semestrální práce 2 znakový strom

Algoritmizace I. Ak. rok 2015/2016 vbp 1. ze 132

Základy algoritmizace a programování

Ukážeme si lineární algoritmus, který pro pevné k rozhodne, zda vstupní. stromový rozklad. Poznamenejme, že je-li k součástí vstupu, pak rozhodnout

Časová a prostorová složitost algoritmů

Reprezentace dat v informačních systémech. Jaroslav Šmarda

1. Převeďte dané číslo do dvojkové, osmičkové a šestnáctkové soustavy: a) b)

Složitosti základních operací B + stromu

IB111 Úvod do programování skrze Python

Prohledávání do šířky = algoritmus vlny

Binární Vyhledávací Stromy, u kterých je. složitost operací v nejhorším. rovná O(log n)

Základní pojmy. Úvod do programování. Základní pojmy. Zápis algoritmu. Výraz. Základní pojmy

Základy programování (IZP)

R zné algoritmy mají r znou složitost

Rekurze. Jan Hnilica Počítačové modelování 12

Předmět: Algoritmizace praktické aplikace

Základy algoritmizace. Hašování

Vyhledávací stromy. Slouží jako pomůcka pro organizaci dat umožňující efektivní vyhledávání.

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. December 7, 2016

Algoritmizace a programování

Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody

4 Stromy a les. Definice a základní vlastnosti stromů. Kostry grafů a jejich počet.

prioritu a vždy je třeba začít pracovat na úkolu, který ma v daný okamžik

Implementace binárního stromu směrníky

Transkript:

Stromy Jan Hnilica Počítačové modelování 14 1

Základní pojmy strom = dynamická datová struktura, složená z vrcholů (uzlů, prvků) propojených hranami hrany chápeme jako orientované, tzn. vedou z uzlu A do uzlu B uzel A je předek (otec) uzlu B, uzel B je potomek (syn) uzlu A kořen = uzel, který nemá předka, strom má jeden kořen list = uzel, který nemá potomky, listů je obvykle více výška stromu = počet hladin, maximální vzdálenost od kořene k listu (měřeno počtem vrcholů mezi kořenem a listem, délku hran nijak neřešíme) A A B A K K - kořen L - listy výška stromu = 3 A A L A L A A L A A žádný vrchol ve stromové struktuře nemá více rodičů stromy jsou speciálním případem tzv. grafů (těmi se budeme zabývat později) A L A L A L Jan Hnilica Počítačové modelování 14 2

Podstromy pro libovolný uzel U platí, že na jeho syny lze pohlížet jako na kořeny podstromů podstromy jsou samy o sobě stromy stromová struktura má přirozeně rekurzivní charakter při práci se stromy se často využívá rekurzivních funkcí uzel U podstrom U podstrom U Jan Hnilica Počítačové modelování 14 3

Obecný a binární strom obecný strom: počet potomků uzlu není nijak omezen binární strom: uzel může mít maximálně dva potomky - binární stromy se používají častěji než obecné obecný strom binární strom Jan Hnilica Počítačové modelování 14 4

Binární strom uzel stromu typedef struct uzel // uložené informace int X; double Y; char Z;... // pointery na syny (podstromy) struct uzel * levy; struct uzel * pravy; Uzel; v programu uchováváme pointer na kořen stromu, který předáváme jako parametr funkcím (stejně jako jsme předávali pointer na první uzel lineárního seznamu) listy mají oba ukazatele na syny nastaveny na NULL Jan Hnilica Počítačové modelování 14 5

Průchod binárním stromem cílem je postupně navštívít a zpracovat všechny uzly stromu (zpracování = výpis, vynulování...) při práci se stromy se často využívá jejich rekurzivní charakter úkol vyřešíme pomocí rekurzivní funkce, která přebírá pointer na kořen stromu K void PruchodStromem(Uzel * K) if (K == NULL) return; ZPRACUJ(K); // zpracujeme aktuální uzel PruchodStromem(K->levy); // průchod levým podstromem PruchodStromem(K->pravy); // průchod pravým podstromem Jan Hnilica Počítačové modelování 14 6

Průchod binárním stromem jsou 3 možnosti, kam umístit funkci pro zpracování uzlu: void PruchodStromem(Uzel * K) if (K == NULL) return; ZPRACUJ(K); // 1: pre-order (před průchodem podstromy) PruchodStromem(K->levy); ZPRACUJ(K); // 2: in-order (mezi průchody oběma podstromy) PruchodStromem(K->pravy); ZPRACUJ(K); // 3: post-order (po průchodu podstromy) A pořadí zpracovávaných uzlů B C pre-order: A B D E C F G in-order: D B E A F C G D E F G post-order: D E B F G C A Jan Hnilica Počítačové modelování 15 7

Binární vyhledávací strom (BVS) datová struktura k rychlému ukládání a vyhledávání údajů podle hodnoty klíče klíč = jedna z položek uzlu pro každý uzel stromu platí: všechny uzly v jeho levém podstromu mají menší hodnotu klíče všechny uzly v jeho pravém podstromu mají větší hodnotu klíče 15 10 24 7 12 17 30 1 9 13 28 obecně může strom obsahovat i více uzlů se stejným klíčem (pak by např. v levém podstromu byly uzly s klíčem klíč kořene) Jan Hnilica Počítačové modelování 14 8

Binární vyhledávací strom (BVS) Uzel pro jednoduchost bude obsahovat jedinou proměnnou typu int typedef struct uzel int hodnota; // uložená informace struct uzel *levy, *pravy; // pointery na syny Uzel; Vytvoření nového uzlu funkce vrací pointer na nově vytvořený uzel (tzn. vrací paměťovou adresu, na které uzel leží) Uzel * NovyUzel(int h) Uzel * U = (Uzel*)malloc(sizeof(Uzel)); U->hodnota = h; U->levy = U->pravy = NULL; return U; Jan Hnilica Počítačové modelování 14 9

Binární vyhledávací strom (BVS) Vyhledání hodnoty průchod od kořene k listům, v každém uzlu se podle hodnoty klíče rozhodujeme, zda pokračovat doprava či doleva (popř. zda jsme uzel už našli) neprocházíme celý strom, ale jedinou cestu od kořene k listům funkce přebírá pointer na kořen stromu a hledanou hodnotu, vrací pointer na uzel s požadovanou hodnotou, případně NULL, pokud uzel ve stromu není Uzel * Hledej(Uzel * K, int hodnota) while (K!= NULL && K->hodnota!= hodnota) if (hodnota > K->hodnota) K = K->pravy; else K = K->levy; return K; Jan Hnilica Počítačové modelování 14 10

Binární vyhledávací strom (BVS) Vyhledání hodnoty rekurzivní varianta funkce Uzel * Hledej(Uzel * K, int hodnota) if (K == NULL K->hodnota == hodnota) return K; if (hodnota > K->hodnota) return Hledej(K->pravy, hodnota); else return Hledej(K->levy, hodnota); Jan Hnilica Počítačové modelování 14 11

Binární vyhledávací strom (BVS) Přidání hodnoty hodnotu ukládáme do nového listu, přitom je potřeba zachovat strukturu podle pravidel BVS uzel s novou hodnotou připojujeme tam, kde ho pak budeme hledat průchod stromem jako při hledání, dokud nerazíme na konec větve (NULL), přitom udržujeme pointer na předka, za který nový uzel připojíme časová složitost: jeden průchod od kořene k listu (výška stromu) funkce přebírá pointer na kořen stromu odkazem (může ho změnit, pokud byl doposud NULL) void Pridej(Uzel ** K, int hodnota) // strom byl dosud prázdný if (*K == NULL) *K = NovyUzel(hodnota); return; // pracovní indexy Uzel *P = *K; // pro hledaní pozice nového uzlu Uzel *Q = *K; // předek nového uzlu Jan Hnilica Počítačové modelování 14 12

Binární vyhledávací strom (BVS) Přidání hodnoty (pokračování kódu z předchozí strany) // najdeme místo pro nový uzel while (P!= NULL) Q = P; if (hodnota == P->hodnota) return; if (hodnota > P->hodnota) P = P->pravy; else P = P->levy; // vytvoříme nový uzel a připojíme ho za Q P = NovyUzel(hodnota); if (hodnota > Q->hodnota) Q->pravy = P; else Q->levy = P; Pridej(&K, hodnota); // volání funkce v programu Jan Hnilica Počítačové modelování 14 13

Binární vyhledávací strom (BVS) Přidání hodnoty totéž jako rekurzivní funkce Uzel * PridejRek(Uzel * K, int hodnota) if (K == NULL) K = NovyUzel(hodnota); else if (hodnota > K->hodnota) K->pravy = PridejRek(K->pravy, hodnota); else if (hodnota < K->hodnota) K->levy = PridejRek(K->levy, hodnota); return K; K = Pridej(K, hodnota); // volání funkce v programu Jan Hnilica Počítačové modelování 14 14

Binární vyhledávací strom (BVS) Smazání hodnoty nejprve musíme nalézt rušený uzel a jeho předka uzel U, obsahující odstraňovanou hodnotu: a. je list smažeme ho, v jeho předkovi nastavíme příslušný pointer na NULL b. má jednoho syna smažeme ho, přepojíme jeho syna na místo smazaného uzlu (předek U pak ukazuje na syna U místo na U) c. má dva syny nemůžeme ho smazat (syny by nebylo kam zapojit) hodnotu v uzlu U nahradíme hodnotou h, což může být a) největší hodnota levého podstromu U b) nejmenší hodnota pravého podstromu U uzel obsahující h je buďto list, nebo má jednoho syna smažeme ho jedním z výše uvedených postupů Pozn. Rozmyslete si, že uvedený výběr uzlu s hodnotou h zaručuje, že strom zůstane platným BVS. časová složitost smazání hodnoty opět odpovídá výšce stromu algoritmus si zkuste napsat sami jako cvičení Jan Hnilica Počítačové modelování 14 15

Binární vyhledávací strom (BVS) Setřídění uložených hodnot průchod do hloubky metodou in-order + výpis hodnot (popř. zápis do nějakého pole) void VypisVzestupne(Uzel * K) if (K == NULL) return; VypisVzestupne(K->levy); // vypíšeme všechny menší hodnoty printf( %i,, K->hodnota); // vypíšeme hodnotu uzlu VypisVzestupne(K->pravy); // vypíšeme všechny větší hodnoty 15 10 24 7 12 17 30 výstup: 1, 7, 9, 10, 12, 13, 15, 17, 24, 28, 30, 1 9 13 28 Jan Hnilica Počítačové modelování 14 16

Binární vyhledávací strom (BVS) Výška BVS operace s BVS (hledání, přidávání a mazání) mají časovou složitost odpovídající výšce stromu výška stromu ale velmi závisí na pořadí, ve kterém hodnoty do stromu přidáváme a odebíráme (analogie quicksort a výběr pivota) Krajní varianty (pro strom obsahující n uzlů): A) zcela vyvážený strom, výška log 2 n B) zcela degenerovaný strom, výška = n lze ukázat, že pokud do stromu přidáváme a rušíme hodnoty v náhodném pořadí, výška stromu je cca 1.4 log 2 n ( pro velká n je to velmi dobrá časová složitost) Jan Hnilica Počítačové modelování 14 17

Vyvažování stromů cílem je zajistit, že operace hledání, přidávání a mazání hodnot budou mít zaručenu logaritmickou časovou složitost O(log n) Definice dokonale vyvážený binární vyhledávací strom (DV BVS) pro každý uzel platí, že počet uzlů v levém a pravém podstromu se liší max. o 1 nejlepší možné vyvážení, ale je obtížné ho udržovat během přidávání a mazání hodnot AVL strom pro každý uzel platí, že výška jeho levého a pravého podstromu se liší max. o 1 slabší forma vyvážení, ale stačí k udržení logaritmické složitosti a je mnohem snáze udržovatelná název podle autorů: Adeľson-Velskij, Landis (1962) AVL strom, který není DV BVS Pozn. Operace s AVL stromy přesahují rámec tohoto kurzu. Zájemce nalezne jejich popis např. v Kombinatorické algoritmy (L. Kučera) Algoritmy a štruktúry údajov (N. Wirth) (orig. Algorithms + data structures = programs) Jan Hnilica Počítačové modelování 14 18

Halda (heap) Definice binární strom, který splňuje následující pravidla: 1. všechny hladiny s výjimkou poslední jsou zcela zaplněny 2. všechny prvky v poslední hladině jsou umístěny co nejvíc vlevo 3. pro každý uzel platí: hodnota v něm uložená je menší než hodnoty v jeho synech z definice plyne: 1. nejmenší hodnota je v kořeni 2. výška haldy obsahující n hodnot je cca log 2 n Využití pokud potřebujeme opakovaně a rychle zjišťovat a odebírat minimum z uložených hodnot (a přitom průběžně přidávat další hodnoty) třídění haldou (heapsort) 5 Pozn. Haldu můžeme realizovat i jako maximovou (otec > syn, maximum v kořeni), tzn. pomocí stejných algoritmů lze efektivně pracovat s maximy uložených hodnot. 7 14 11 9 37 15 14 27 13 Jan Hnilica Počítačové modelování 14 19

Haldové operace Zjištění minima minimum je vždy v kořeni konstantní časová složitost O(1) Přidání hodnoty hodnotu přidáme do nového listu, ten musíme vytvořit na poslední hladině co nejvíce vlevo upravíme haldu - novou hodnotu opakovaně prohazujeme s hodnotou v předkovi, dokud je předek větší (s novou hodnotou "proskáčeme" stromem vzhůru) uvědomte si, že tato prohození neporuší uspořádání haldy (proč?) časová složitost odpovídá výšce haldy, tzn. O(log n) Odstranění minima minimum v kořeni nahradíme hodnotou z posledního uzlu, poslední uzel smažeme (poslední uzel je na spodní hladině co nejvíc vpravo) upravíme haldu - s hodnotou vloženou do kořene proskáčeme stromem dolů tzn. pokud je hodnota větší než hodnota některého ze synů, prohodíme je (pokud je větší než oba synové, prohodíme s menším z nich) opět platí, že tato prohození neporuší uspořádání haldy časová složitost opět odpovídá výšce haldy, tzn. O(log n) Jan Hnilica Počítačové modelování 14 20

Uložení haldy v poli haldu lze snadno uložit do běžného 1-rozměrného pole jednotlivé uzly indexujeme po vrstvách zleva doprava: 0 5 1 2 7 14 3 4 5 6 11 9 37 15 0 1 2 3 4 5 6 7 8 9 5 7 14 11 9 37 15 14 27 13 7 8 9 14 27 13 uzel s indexem [i] má syny na indexech [2i + 1] a [2i + 2] předka na indexu [i / 2] (pro liché i) [i / 2 + 1] (pro sudé i) Jan Hnilica Počítačové modelování 14 21

Haldové operace v poli v ukázkách budeme pracovat s haldou hodnot typu double halda bude uložena v poli o n prvcích mějme na paměti, že při použití pole je nutné vždy testovat, jestli je pro přidání dalšího prvku ještě místo, zrovna tak je potřeba ošetřit, zda neodebíráme minimum z prázdné haldy tyto testy si čtenář doplní sám, v ukázkách nebudou uvedeny z důvodu úspory místa úvodem vytvoříme funkci pro výpočet indexu předka prvku, ležícího v poli na indexu i int IndexPredka(int i) if (i % 2 == 0) return (i / 2-1); else return (i / 2); Jan Hnilica Počítačové modelování 14 22

Haldové operace v poli Přidání hodnoty do haldy do haldy přidáváme číslo c, proměnná pocet vyjadřuje aktuální počet hodnot na haldě void PridejHodnotu(double c, double halda[], int * pocet) // hodnotu uložíme na konec haldy (*pocet)++; halda[*pocet] = c; // upravíme haldu double pomocny; int umistovany = *pocet - 1; // index umísťovaneho prvku int predek = IndexPredka(umistovany); // index předka while (umistovany > 0 && halda[umistovany] < halda[predek]) // prohozeni prvků pomocny = halda[umistovany]; halda[umistovany] = halda[predek]; halda[predek] = pomocny; // posun nahoru umistovany = predek; predek = indexpredka(umistovany); Jan Hnilica Počítačové modelování 14 23

Haldové operace v poli Odstranění minima z haldy double OdeberMinimum(double halda[], int * pocet) // uložíme si odebirané minimum double min = halda[0]; // snížíme velikost haldy, poslední prvek vložíme do kořene (*pocet)--; halda[0] = halda[*pocet]; // proměnné pro úpravu haldy int umistovany = 0; // index umísťované hodnoty int syn = 2 * umistovany + 1; // index menšího syna double pomocny; pokračování kódu na další straně Jan Hnilica Počítačové modelování 14 24

Haldové operace v poli odstranění minima - pokračování kódu z předchozí strany // úprava haldy = proskákání stromem dolů while (syn < *pocet) if (syn + 1 < *pocet) // test druhého syna if (halda[syn + 1] < halda[syn]) syn++; if (halda[umistovany] > halda[syn]) // prohodit pomocny = halda[umistovany]; halda[umistovany] = halda[syn]; halda[syn] = pomocny; // posunout dolů umistovany = syn; syn = 2 * umistovany + 1; else break; // funkce vrací minimum, odebrané v úvodu z kořene return min; Jan Hnilica Počítačové modelování 14 25

Třídění haldou - heapsort Cíl: setřídit údaje uložené v poli při použití haldových operací Postup: z hodnot v poli vytvoříme haldu na počátku halda tvořena jediným prvkem (prvním prvkem vlevo) (n-1) krát přidáme prvek do haldy, přidáváme vždy první prvek zprava halda se postupně tvoří v levé části pole n-krát odebereme minimum z haldy minima odebíráme z kořene (prvek na nultém indexu) halda se postupně zmenšuje, minima ukládáme doprava, na místa uvolněná po haldě časová složitost: (n-1)-krát přidání a n-krát odebrání prvku, celkově O(n log n) paměťová složitost: třídíme přímo v poli, O(n) pozn. po provedení tohoto algoritmu jsou čísla v poli uspořádána sestupně (minima byla ukládána zprava) - jaké jsou možnosti, když chceme vzestupné uspořádání? Jan Hnilica Počítačové modelování 14 26

Obecný strom počet synů není omezen pro uložení pointerů na syny se nabízí několik variant: 1) Pole pointerů na syny použitelné, pokud předem známe maximální možný počet synů (označme ho S) typedef struct uzel int hodnota; struct uzel * synove[s]; Uzel; každý uzel alokuje paměť pro uložení S pointerů, z nichž bude u většiny uzlů využita jen část pro velké S paměťově neúnosné funkce pro průchod stromem do hloubky void Pruchod(Uzel * K) Zpracuj(K); for (int i = 0; i < S; i++) if (K->synove[i]!= NULL) Pruchod(K->synove[i]); Jan Hnilica Počítačové modelování 14 27

Obecný strom 2) Lineární seznam pointerů na syny ve stromové struktuře jsou propojeny dva typy uzlů: NULL uzel stromu uzel seznamu synů // 1. uzel stromu typedef struct uzel int hodnota; // uložená informace struct seznam * synove; // pointer na počátek seznamu synů Uzel; // 2. uzel seznamu synů typedef struct seznam Uzel * syn; // pointer na synovský uzel stromu struct seznam * dalsi; // pointer na bratra v seznamu Seznam; Jan Hnilica Počítačové modelování 14 28

Obecný strom 2) Lineární seznam pointerů na syny průchod stromem do hloubky (K je pointer na kořen stromu) void Pruchod(Uzel * K) if (K == NULL) return; Zpracuj(K); Seznam * S = K->synove; while (S!= NULL) Pruchod(S->syn); S = S->dalsi; Jan Hnilica Počítačové modelování 14 29

Obecný strom 3) Kanonická reprezentace binárním stromem uzel obsahuje dva pointery (oba typu Uzel*) 1. na prvního syna 2. na mladšího bratra listy mají pointer syn nastavený na NULL synové jednoho uzlu jsou propojeni přes pointery bratr informace syn bratr typedef struct uzel int hodnota; struct uzel *syn, *bratr; Uzel; 1 1 NULL 2 3 4 2 3 4 NULL 5 6 7 8 NULL 5 6 7 8 NULL NULL NULL NULL NULL NULL Jan Hnilica Počítačové modelování 14 30

Písmenkový strom (trie) struktura umožňující úsporné uložení slovníku (množiny řetězců) a rychlé vyhledávání slov příklad: k e m o s t o y r p u a uložená slova: n y sto strom stromek stromy strop struna struny uzly uhraničené tečkovanou čarou signalizují konec slova operace vyhledání, přidání a smazání slova složitost daná délkou slova (nikoliv délkou slovníku) Jan Hnilica Počítačové modelování 14 31

Písmenkový strom (trie) Způsob uložení pointerů na syny uzlu velmi závisí na možném počtu znaků, kterými slovo může pokračovat tuto množinu znaků označujeme jako abecedu, značíme Σ počet znaků označujeme jako tzv. velikost abecedy, značíme Σ Malé abecedy pole pointerů (indexované např. ASCII kódy znaků) výhodou je okamžitý přístup k pointeru na další znak slova O(1) struct uzel int konecslova; // 0 nebo 1 struct uzel * synove[26]; // např. pro abecedu a z (ascii 97-122) ; Rozsáhlé abecedy lineární seznam pointerů výhoda: nebudou alokovány nevyužité pointery nevýhoda: prodlouží se hledání dalšího znaku O( Σ ) binární vyhledávací strom pointerů rychlejší vyhledávání dalšího znaku O(log Σ ) Jan Hnilica Počítačové modelování 14 32