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

Podobné dokumenty
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

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

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

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

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

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

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

Stromy. Jan Kybic.

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

Algoritmy a datové struktury

Anotace. Dámy na šachovnici dominance a nezávislost. Aritmetické výrazy, notace a převody mezi nimi, nejdelší rostoucí podposloupnost.

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í

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

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

Stromy. Příklady. Rekurzivní datové struktury. Základní pojmy

Binární soubory (datové, typované)

Implementace aritmetického stromu pomocí směrníků

Programovací jazyk Pascal

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

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

Řešení: PŘENESVĚŽ (N, A, B, C) = přenes N disků z A na B pomocí C

Stromy, haldy, prioritní fronty

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

Časová a prostorová složitost algoritmů

Binární vyhledávací stromy

Dynamické datové struktury IV.

Vyučovací hodina. 1vyučovací hodina: 2vyučovací hodiny: Opakování z minulé hodiny. Procvičení nové látky

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

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

- znakové konstanty v apostrofech, např. a, +, (znak mezera) - proměnná zabírá 1 byte, obsahuje kód příslušného znaku

NPRG030 Programování I, 2016/17 1 / :58:13

NMIN102 Programování /2 Z, Zk

OSTRAVSKÁ UNIVERSITA V OSTRAVĚ Pedagogická fakulta Obor informační technologie ve vzdělávání Kombinované studium

Předmět: Algoritmizace praktické aplikace

Dynamické datové struktury II.

NPRG030 Programování I, 2010/11

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

Algoritmizace prostorových úloh

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

ABSTRAKTNÍ DATOVÉ TYPY

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

Abstraktní datové typy FRONTA

Algoritmy výpočetní geometrie

Prioritní fronta, halda

Da D to t v o é v ty t py IB111: Datové typy

1. Implementace funkce počet vrcholů. Předmět: Algoritmizace praktické aplikace (3ALGA)

ADT STROM Lukáš Foldýna

Implementace LL(1) překladů

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

Implementace seznamů do prostředí DELPHI pomocí lineárního seznamu

Rekurzivní algoritmy

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

a) b) c) Radek Mařík

NPRG030 Programování I, 2017/18 1 / :22:16

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

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

type Obdelnik = array [1..3, 1..4] of integer; var M: Obdelnik;

Algoritmizace prostorových úloh

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

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

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

Datové struktury Úvod

Texty k Programování na VŠFS. Petr Kučera () Texty k Programování na VŠFS 29. května / 117

Anotace. zpět k rekurzi: teorie her. Martin Pergel,

Dynamické datové struktury III.

Datové typy a struktury

Radek Mařík

součet cvičení celkem. známka. Úloha č.: max. bodů: skut. bodů:

Rekurze. Pavel Töpfer, 2017 Programování 1-8 1

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

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

5 Přehled operátorů, příkazy, přetypování

Rekurze a zásobník. Jak se vypočítá rekurzivní program? volání metody. vyšší adresy. main(){... fa(); //push ret1... } ret1

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

TGH07 - Chytré stromové datové struktury

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

Algoritmizace a programování

BINARY SEARCH TREE

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

NPRG030 Programování I, 2018/19 1 / :25:37

Čtvrtek 8. prosince. Pascal - opakování základů. Struktura programu:

Pascal. Katedra aplikované kybernetiky. Ing. Miroslav Vavroušek. Verze 7

1. D Y N A M I C K É DAT O V É STRUKTUR Y

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

Pokročilá algoritmizace amortizovaná složitost, Fibonacciho halda, počítačová aritmetika

Binární vyhledávací stromy II

TGH07 - Chytré stromové datové struktury

1.1 Struktura programu v Pascalu Vstup a výstup Operátory a některé matematické funkce 5

R zné algoritmy mají r znou složitost

Slepé prohledávání do šířky Algoritmus prohledávání do šířky Při tomto způsobu prohledávání máme jistotu, že vždy nalezneme koncový stav, musíme ale p

V každém kroku se a + b zmenší o min(a, b), tedy vždy alespoň o 1. Jestliže jsme na začátku dostali 2

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

- speciální symboly + - * / =., < > <> <= >= a další. Klíčová slova jsou chráněnými útvary, které nelze použít ve významu identifikátorů.

Úvod do programovacích jazyků (Java)

BINARY SEARCH TREE

Náznak ukázky syntaxe a sémantiky pro projekt. 1 Syntaktické prvky. Poslední aktualizace: 8.

Anotace. Jednotky (tvorba a využití), struktury (typ record),

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

Paradigmata programování 1

autoři: Rudolf Bayer, Ed McCreight všechny vnější uzly (listy) mají stejnou hloubku ADS (abstraktní datové struktury)

Transkript:

Reprezentace aritmetického výrazu - binární strom reprezentující aritmetický výraz (2 + 5) * (13-4) * + - 2 5 13 4 - listy stromu obsahují operandy (čísla) - vnitřní uzly obsahují operátory (znaménka) - závorky ve stromě nejsou, pořadí vyhodnocení je určeno strukturou stromu Pavel Töpfer, 2019 Programování 2-11 1

type Uk = ^Uzel; Uzel = record Znam: char; {znaménko + - * /} Hod: real; {hodnota uložená v listu} L, R: Uk {levý a pravý syn} end; - neukládají se závorky (uzávorkování je kódováno strukturou stromu) - je třeba odlišit listy (např. položka Znam = @, nebo stačí L = nil) (2 + 5) * (13-4) * + - 2 5 13 4 Pavel Töpfer, 2019 Programování 2-11 2

Vyhodnocení aritmetického výrazu reprezentovaného binárním stromem rekurzívně (metoda Rozděl a panuj): function Vyhodnot(K: uzel): real; {K je ukazatel na kořen stromu} begin if K je list then Vyhodnot := hodnota listu K else begin L := Vyhodnot(levý podstrom uzlu K); R := Vyhodnot(pravý podstrom uzlu K); Vyhodnot := s hodnotami podstromů proveď operaci určenou znaménkem v uzlu K; end end; Pavel Töpfer, 2019 Programování 2-11 3

function Vyhodnot(K: Uk): real; {K je ukazatel na kořen stromu} begin with K^ do case Znam of '@': Vyhodnot := Hod; '+': Vyhodnot := Vyhodnot(L) + Vyhodnot(R); '-': Vyhodnot := Vyhodnot(L) - Vyhodnot(R); '*': Vyhodnot := Vyhodnot(L) * Vyhodnot(R); '/': Vyhodnot := Vyhodnot(L) / Vyhodnot(R) end end; Pavel Töpfer, 2019 Programování 2-11 4

Notace aritmetického výrazu - průchod binárním stromem reprezentujícím aritmetický výraz - v navštívených uzlech vypisujeme uloženou hodnotu (2 + 5) * (13-4) * + - 2 5 13 4 průchod preorder PREFIX * + 2 5-13 4 průchod inorder INFIX (bez závorek!) 2 + 5 * 13-4 průchod postorder POSTFIX 2 5 + 13 4 - * Pavel Töpfer, 2019 Programování 2-11 5

průchod preorder PREFIX * + 2 5-13 4 průchod inorder INFIX (bez závorek!) 2 + 5 * 13-4 průchod postorder POSTFIX 2 5 + 13 4 - * - vždy stejné pořadí operandů listy stromu procházíme ve všech případech zleva doprava - v prefixovém zápisu operátor bezprostředně předchází své dva operandy, v postfixovém je následuje - v prefixovém a postfixovém zápisu výrazu nejsou závorky, pořadí vyhodnocování je plně určenou strukturou výrazu - inorder průchod stromem vytvořil chybný infixový zápis bez závorek, z něhož není zřejmé pořadí vyhodnocování výrazu Terminologická poznámka: prefix = polská notace (Polish notation) Łukasiewicz postfix = reverzní polská notace (reverse Polish notataion, RPN) Pavel Töpfer, 2019 Programování 2-11 6

Získání správného infixového zápisu výrazu: procedure Infix(K: uzel); begin if K je list then write(hodnota uzlu K - číslo) else begin write('('); Infix(levý syn uzlu K); write(hodnota uzlu K - znaménko); Infix(pravý syn uzlu K); write(')') end end; Pavel Töpfer, 2019 Programování 2-11 7

Vyhodnocení výrazu v postfixové notaci - snadné, využití např. u kalkulaček, v překladačích - jeden průchod zápisem výrazu zleva doprava - zásobník na ukládání číselných hodnot Postup zpracování postfixového zápisu: číslo vložit do zásobníku znaménko vyzvednout ze zásobníku horní dvě čísla provést s nimi operaci určenou znaménkem výsledek operace vložit do zásobníku konec na zásobníku je jediné číslo = hodnota výrazu - pozor na pořadí operandů u nekomutativních operátorů (na vrcholu zásobníku je pravý operand, pod ním levý) - časová složitost O(N), kde N je délka výrazu Pavel Töpfer, 2019 Programování 2-11 8

Vyhodnocení výrazu v prefixové notaci 1. možnost: - průchod výrazem odzadu, postup jako u postfixu - pouze se změní pořadí operandů při vyzvednutí ze zásobníku: na vrcholu zásobníku je levý operand, pod ním pravý - časová složitost O(N), kde N je délka výrazu Pavel Töpfer, 2019 Programování 2-11 9

2. možnost: - jeden průchod zápisem výrazu zleva doprava - zásobník na ukládání znamének a číselných hodnot Postup zpracování prefixového zápisu odpředu: - znaménko nebo číslo vložit do zásobníku - když se na vrcholu zásobníku sejdou dvě čísla vyzvednout je ze zásobníku, dále vyzvednout znaménko uložené pod nimi, provést s čísly operaci určenou znaménkem a výsledek operace vložit do zásobníku (což může opětovně vyvolat tentýž proces vyhodnocení) - konec na zásobníku je jediné číslo = hodnota výrazu - pozor na pořadí operandů u nekomutativních operátorů (na vrcholu zásobníku je pravý operand, pod ním levý) - časová složitost O(N), kde N je délka výrazu Pavel Töpfer, 2019 Programování 2-11 10

3. možnost: rekurze - rekurzivní funkce na vyčíslení prefixového zápisu od zadaného indexu - když je prvním znakem výrazu číslice, výrazem je jen jedno číslo funkce vrátí jeho hodnotu (a posune index za něj) - když je prvním znakem znaménko, funkce provede dvě rekurzivní volání a s výsledky vykoná operaci naznačenou tímto znaménkem - celkem se provede jeden průchod zápisem výrazu zleva doprava - časová složitost O(N), kde N je délka výrazu Pavel Töpfer, 2019 Programování 2-11 11

Převod infix postfix - jeden průchod zápisem výrazu zleva doprava, časová složitost O(N) - zásobník na ukládání znamének - v postfixovém zápisu jsou čísla ve stejném pořadí jako v infixovém, znaménka je třeba pozdržet na zásobníku Postup zpracování infixového zápisu: číslo zapsat přímo na výstup levá ( do zásobníku pravá ) ze zásobníku postupně přenést na výstup všechna znaménka až k nejbližší uložené levé závorce, pak levou ( ze zásobníku i pravou ) ze vstupu zrušit znaménko do zásobníku předtím ale ze zásobníku postupně přenést na výstup všechna znaménka vyšší nebo stejné priority, nejvýše ale k první uložené levé ( konec ze zásobníku přenést na výstup všechna znaménka Pavel Töpfer, 2019 Programování 2-11 12

Vyhodnocení výrazu v infixové notaci - spojení dvou předchozích algoritmů: * převod výrazu z infixu do postfixu v čase O(N) * vyhodnocení postfixové notace v čase O(N) celková časová i paměťová složitost O(N) - obě fáze výpočtu se mohu provádět * buď postupně (s uložením vytvořené postfixové notace výrazu) * nebo souběžně (vznikající postfixová notace se neukládá, ale rovnou průběžně vyhodnocuje) algoritmus používá dva zásobníky jeden na znaménka a druhý na čísla Pavel Töpfer, 2019 Programování 2-11 13

Postavení binárního stromu ze zápisu výrazu postfixová nebo prefixová notace algoritmus podobný jako při vyhodnocování výrazu, do zásobníku se vždy ukládá odkaz (adresu) na nově vytvořený uzel a místo provádění operací se uzly s operandy zapojují pod uzel s operátorem jako jeho synové infixová notace nejprve ji převedeme na postfixovou notaci Pavel Töpfer, 2019 Programování 2-11 14

Binární vyhledávací strom BVS (BST - binary search tree) - datová struktura pro ukládání a vyhledávání dat podle klíče - pro každý uzel platí: všechny záznamy uložené v levém podstromu mají menší klíč všechny záznamy uložené v pravém podstromu mají větší klíč (platí pro všechny záznamy v podstromu, nestačí jen pro syny!) při vyhledávání není třeba procházet celý strom, stačí projít jednu cestu od kořene k listu časová složitost vyhledávání je v nejhorším případě určena výškou stromu Pavel Töpfer, 2019 Programování 2-11 15

Výška H binárního stromu o N uzlech = délka nejdelší cesty z kořenu do listu minimum vyvážený strom N = 2 0 + 2 1 + 2 H = 2 H+1 1 maximum degenerovaný strom H N H log 2 N v průměrném případě výška O(log N) Pavel Töpfer, 2019 Programování 2-11 16

Hledání hodnoty v BVS function Hledej(P: Uk; H: integer): Uk; {v BVS s kořenem P hledá hodnotu H, vrací odkaz na nalezený uzel, resp. nil} var Sestup: boolean; begin Sestup := P <> nil; while Sestup do begin if H = P^.Hodnota then Sestup := false else if H < P^.Hodnota then P := P^.L else {H > P^.Hodnota} P := P^.R; if P = nil then Sestup := false end; Hledej := P; end; Pavel Töpfer, 2019 Programování 2-11 17

Rekurzivní řešení téže funkce: function Hledej(P: Uk; H: integer): Uk; {v BVS s kořenem P hledá hodnotu H, vrací odkaz na nalezený uzel, resp. nil} begin if P = nil then Hledej := nil else if H = P^.Hodnota then Hledej := P else if H < P^.Hodnota then Hledej := Hledej(P^.L, H) else {H > P^.Hodnota} Hledej := Hledej(P^.R, H) end; Pavel Töpfer, 2019 Programování 2-11 18

Přidání hodnoty do BVS - novou hodnotu musíme přidat tam, kde ji budeme hledat - přidává se vždy do nového listu - postupuje se stejně jako při hledání hodnoty v BVS, dokud se nenarazí na nil-ový ukazatel a do toho místa se přidá nový uzel - technická realizace: při průchodu stromem od kořene k listu udržovat pomocný ukazatel o jeden krok pozadu, pomocí něj pak připojit do stromu nový uzel - časová složitost je opět dána výškou stromu, v průměrném případě O(log N) Pavel Töpfer, 2019 Programování 2-11 19

Vypuštění hodnoty z BVS - nejprve průchodem od kořene směrem k listu najít uzel s vypouštěnou hodnotou (a jeho předchůdce ve stromě) - pokud je to list, zruší se (v předchůdci nastavit nil) - pokud má jen jednoho následníka, uzel se zruší a jeho následník se přepojí místo něj (předchůdce tedy bude místo na rušený uzel ukazovat na jeho jediného následníka) - pokud má dva následníky, uzel se nemůže fyzicky zrušit; smaže se jen jeho dosavadní hodnota a nahradí se jinou vhodnou hodnotou ze stromu. Tou je buď nejmenší hodnota z pravého podstromu nebo naopak největší hodnota z levého podstromu rušeného uzlu. Tato náhradní hodnota leží jistě v listu nebo v uzlu s jediným následníkem, její původní uzel tedy umíme snadno zrušit. Pavel Töpfer, 2019 Programování 2-11 20

- časová složitost vypuštění uzlu z BVS je opět dána výškou stromu, v průměrném případě O(log N) celkově se prošlo stromem pouze jednou od kořene k listu Pavel Töpfer, 2019 Programování 2-11 21

Hledání hodnoty v BVS s použitím zarážky (alternativa k předchozímu řešení) - jeden speciální uzel navíc slouží jako zarážka při hledání (vkládá se do něj hledaná hodnota) - všechny ukazatele L, R v uzlech stromu s hodnotou nil nahradíme ukazateli směřujícími na tento uzel function Hledej(P, Zarazka: Uk; H: integer): Uk; begin Zarazka^.Hodnota := H; while P^.Hodnota <> H do if H < P^.Hodnota then P := P^.L else {H > P^.Hodnota} P := P^.R; if P = Zarazka then Hledej := nil else Hledej := P; end; Pavel Töpfer, 2019 Programování 2-11 22

Vyvážené stromy cíl: zajistit výšku stromu O(log N) v případě BVS časová složitost všech operací O(log N) Dokonale vyvážený binární strom pro každý uzel platí: počet uzlů v jeho levém a pravém podstromu se liší nejvýše o 1 - nejlepší možné vyvážení, výška stromu s N uzly je log N - lze snadno postavit z předem známé množiny hodnot - je obtížné udržovat strom dokonale vyvážený při přidávání a odebírání hodnot proto se v praxi používají jiné (slabší) definice vyváženosti, strom nebude tak dokonale vyvážený, ale půjde snadněji udržovat Pavel Töpfer, 2019 Programování 2-11 23

AVL strom (G. M. Adeľson-Velskij, E. M. Landis, 1962) pro každý uzel platí: výška jeho levého a pravého podstromu se liší nejvýše o 1 - slabší požadavek, ale stačí: AVL-strom je maximálně o 45% vyšší než dokonale vyvážený strom se stejným počtem uzlů - každý dokonale vyvážený strom je AVL-stromem - AVL-strom nemusí být dokonale vyvážený Příklad: Pavel Töpfer, 2019 Programování 2-11 24

Postavení dokonale vyváženého binárního stromu s N uzly function DVBS(N: integer): Uk; var S: Uk; begin if N = 0 then DVBS:=nil else begin new(s); S^.L:=DVBS((N-1) div 2); S^.R:=DVBS(N-1 (N-1) div 2); DVBS:=S end end; Funkce vrací ukazatel na kořen sestrojeného stromu. Info-hodnoty uzlů ve stromu zatím nejsou definovány. Pavel Töpfer, 2019 Programování 2-11 25

Postavení dokonale vyváženého binárního vyhledávacího stromu s danými N hodnotami v uzlech 1. varianta řešení: - nejprve postavit dokonale vyvážený binární strom s N uzly pomocí předchozí funkce DVBS (hodnoty uzlů zatím nejsou definovány) - hodnoty setřídit - projít sestrojený strom metodou inorder a přitom do uzlů stromu postupně zapisovat hodnoty v pořadí od nejmenší po největší 2. varianta řešení: - hodnoty nejprve setřídit v poli A[1..N] - při konstrukci stromu rovnou vkládat do Info-položek uzlů hodnoty - parametry funkce Strom určují rozsah indexů v poli A (které hodnoty z pole A patří do příslušného podstromu) - funkce bude volána Strom(1,N), vrací ukazatel na kořen sestrojeného stromu Pavel Töpfer, 2019 Programování 2-11 26

function Strom(X, Y: integer): Uk; var S: Uk; begin if X > Y then Strom:=nil else begin new(s); S^.Info:=A[(X+Y) div 2]; S^.L:=Strom(X, (X+Y) div 2 1); S^.R:=Strom((X+Y) div 2 +1, Y); Strom:=S end end; Pavel Töpfer, 2019 Programování 2-11 27