Rekurzivní algoritmy

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

Stromy, haldy, prioritní fronty

Techniky návrhu algoritmů

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

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

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

4. Rekurze. BI-EP1 Efektivní programování Martin Kačer

Algoritmy výpočetní geometrie

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

Dynamické programování

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

Algoritmy a datové struktury

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.

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

Obsah Techniky návrhu algoritmů Rekurze, algoritmy prohledávání s návratem, dynamické programování Rekurze... 5

Datové struktury 2: Rozptylovací tabulky

TGH07 - Chytré stromové datové struktury

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

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

5. Dynamické programování

Struktura programu v době běhu

Binární vyhledávací stromy II

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

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

PROHLEDÁVÁNÍ GRAFŮ. Doc. RNDr. Josef Kolář, CSc. Katedra teoretické informatiky, FIT České vysoké učení technické v Praze

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

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

Časová a prostorová složitost algoritmů

NEJKRATŠÍ CESTY I. Doc. RNDr. Josef Kolář, CSc. Katedra teoretické informatiky, FIT České vysoké učení technické v Praze

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

TGH07 - Chytré stromové datové struktury

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

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

NP-ÚPLNÉ PROBLÉMY. Doc. RNDr. Josef Kolář, CSc. Katedra teoretické informatiky, FIT České vysoké učení technické v Praze

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

Rozptylování, stromy - zákl. vlastnosti

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

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

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

Prioritní fronta, halda

Mělká a hluboká kopie

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

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

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

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

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

Základní datové struktury

TGH05 - Problém za milion dolarů.

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

Dynamické datové struktury II.

PODOBÁ SE JAZYKU C S NĚKTERÝMI OMEZENÍMI GLOBÁLNÍ PROMĚNNÉ. NSWI162: Sémantika programů 2

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

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

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

Rekurze a rychlé třídění

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

IB111 Úvod do programování skrze Python

A4B33ALG 2010/05 ALG 07. Selection sort (Select sort) Insertion sort (Insert sort) Bubble sort deprecated. Quicksort.

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

Funkce pokročilé možnosti. Úvod do programování 2 Tomáš Kühr

Abstraktní třídy, polymorfní struktury

Dynamické datové struktury III.

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

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

Algoritmy I, složitost

BINARY SEARCH TREE

MATURITNÍ OTÁZKY ELEKTROTECHNIKA - POČÍTAČOVÉ SYSTÉMY 2003/2004 PROGRAMOVÉ VYBAVENÍ POČÍTAČŮ

IB108 Sada 1, Příklad 1 Vypracovali: Tomáš Krajča (255676), Martin Milata (256615)

Datové struktury 1: Základní datové struktury

R zné algoritmy mají r znou složitost

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Úvod do informatiky. Miroslav Kolařík

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

Maturitní otázky z předmětu PROGRAMOVÁNÍ

Rozklad problému na podproblémy

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

STACK

Matematická indukce a správnost programů. Základy diskrétní matematiky, BI-ZDM ZS 2011/12, Lekce 13

Funkce, intuitivní chápání složitosti

Matematická indukce. Základy diskrétní matematiky, BI-ZDM ZS 2011/12, Lekce 3

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

STROMY A KOSTRY. Doc. RNDr. Josef Kolář, CSc. Katedra teoretické informatiky, FIT České vysoké učení technické v Praze. BI-GRA, LS 2010/2011, Lekce 6

Abstraktní datové typy

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

Dynamické datové struktury IV.

Implementace LL(1) překladů

8. Rekurze. doc. Ing. Jiří Vokřínek, Ph.D. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze

ORIENTOVANÉ GRAFY, REPREZENTACE GRAFŮ

BINARY SEARCH TREE

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

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

Grafové algoritmy. Programovací techniky

Hledání k-tého nejmenšího prvku

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.

DYNAMICKÉ PROGRAMOVÁNÍ A PROBLÉM BATOHU

Na začátku rozdělíme práci a určíme, které podproblémy je potřeba vyřešit. Tyto

Programování: základní konstrukce, příklady, aplikace. IB111 Programování a algoritmizace

PROGRAMOVACÍ JAZYKY A PŘEKLADAČE LL SYNTAKTICKÁ ANALÝZA DOKONČENÍ, IMPLEMENTACE.

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

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

Transkript:

Rekurzivní algoritmy prof. Ing. Pavel Tvrdík CSc. Katedra počítačových systémů Fakulta informačních technologií České vysoké učení technické v Praze c Pavel Tvrdík, 2010 Efektivní algoritmy (BI-EFA) ZS 2010/11, Přednáška 8 Evropský sociální fond. Praha & EU: Investujeme do vaší budoucnosti prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 1 / 22

Rekurze Rekurze Rekurze je metoda zápisu algoritmu, kde se stejný postup opakuje na částech vstupních dat. Výhody: úsporná: zápis kódu je kratší a konečným zápisem lze definovat množinu dat, přirozená: opakování a samopodobnost jsou v přírodě běžné, intuitivní: explicite pojmenovává to, co se opakuje v menším, expresivní: rekurzivní specifikace umožňuje snadnou analýzu složitosti a ověření správnosti (viz např. MergeSort v Přednášce 5). Nevýhody: Interpretace nebo provádění rekurzivního kódu používá systémový zásobník pro předání parametrů volání a proto vyžaduje systémovou paměť. Dynamická alokace systémového zásobníku a ukládání parametrů na něj navíc představuje časovou režii. prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 2 / 22

Typy rekurze Koncová rekurze Typy rekurze Koncová rekurze: rekurzivní volání je posledním příkazem algoritmu, po kterém se už neprovádějí žádné další odložené operace. Příklad 1 (Euclidův algoritmus) Největší společný dělitel: Nechť n m 0. { n if m = 0, GCD(n, m) = GCD(m, Remainder(n, m)) if m > 0. prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 3 / 22

Typy rekurze Lineární rekurze Lineární rekurze: V těle algoritmu je pouze jedno rekurzivní volání anebo jsou dvě, ale vyskytují se v disjunktních větvích podmíněných příkazů a nikdy se neprovedou současně. Strom rekurzivních volání je lineární. Příklad 2 (Vložení prvku do BVS) procedure insertrec(x, z, p) { (1) if (x = Null) (2) {P arent[z] p; return z}; (3) Cnt[x] + +; (4) if (V al[z] < V al[x]) (5) then Lef t[x] insertrec(lef t[x], z, x) (6) else Right[x] insertrec(right[x], z, x); (7) return x; } prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 4 / 22

Typy rekurze Kaskádní rekurze Kaskádní rekurze: V těle algoritmu jsou vedle sebe aspoň dvě rekurzivní volání. Viz MergeSort, QuickSort. Příklad 3 (Fibonacciho posloupnost) { 1 if n = 1, 2, F(n) = F(n 1) + F(n 2) if n > 2. Příklad 4 (Obecná lineární rekurence) F(n) = { 1 if n 3, a 1 F(n 1) + a 2 F(n 2) + a 3 F(n 3) if n > 3. Strom rekurzivních volání je více-ární. prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 5 / 22

Typy rekurze Vnořená rekurze Vnořená rekurze: Algoritmus volaný rekurzivně s parametry, jejichž hodnoty jsou také výsledkem rekurzivního volání. Příklad 5 (Ackermannova funkce) n + 1 if m = 0, A(m, n) = A(m 1, 1) if m > 0 and n = 0, A(m 1, A(m, n 1)) if m > 0 and n > 0. Neuvěřitelně rychle rostoucí funkce, viz http://mathworld.wolfram.com/ackermannfunction.html. prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 6 / 22

Rekurze vs. iterace Rekurze vs. iterace Rekurzivní programování má základní oporu v teoretické informatice, kde bylo dokázáno, že: 1 Každou funkci, která může být implementovaná na vonneumannovském počítači, lze vyjádřit rekurzivně bez použití iterace. 2 Každá rekurzivní funkce se dá vyjádřit iterativně s použitím zásobníku (implicitní zásobník se stane viditelný uživateli). Koncovou rekurzi lze vždy nahradit iterací bez nutnosti zásobníku. (Zformulujte intuitivně zřejmý důvod.) V předchozích přednáškách bylo několik případů konverze rekurzivního algoritmu na iterační. prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 7 / 22

Rekurze vs. iterace Rekurzivní heapify procedure heapifyrec(a, i) { (1) l left(i); (2) r right(i); (3) if (l Heap Size(A) & A[l] > A[i]) (4) then Largest l else Largest i; (5) if (r Heap Size(A) & A[r] > A[Largest]) (6) then Largest r; (7) if (Largest i) (8) then {A[i] A[Largest]; heapifyrec(a, Largest)} } prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 8 / 22

Rekurze vs. iterace Iterativní heapify procedure heapifyiter(a, i) { (1) while (i Heap Size(A)/2 ) (2) do {l left(i); (3) r right(i); (4) if (l Heap Size(A) & A[l] > A[i]) (5) then Largest l else Largest i; (6) if (r Heap Size(A) & A[r] > A[Largest]) (7) then Largest r; (8) if (Largest = i) return(); (9) A[i] A[Largest]; (10) i Largest; } }; prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 9 / 22

Rekurze vs. iterace Rekurzivní QuickSort procedure QuickSort(A, low, high) { (1) if (low < high) (2) then { pivot SelectPivot(A, low, high); (3) mid Rozdel(A, low, high, pivot); (4) QuickSort(A, low, mid); (5) QuickSort(A, mid + 1, high) } } prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 10 / 22

Rekurze vs. iterace Méně rekurzivní QuickSort procedure QuickSortTail(A, low, high) { (1) while (low < high) (2) do { pivot SelectPivot(A, low, high); (3) mid Rozdel(A, low, high, pivot); (4) QuickSortTail(A, low, mid); (5) low mid + 1 } } prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 11 / 22

Rekurzivní algoritmy nad stromy Algoritmy nad binárními stromy Binární strom je definován rekurzivně (viz Slajd 10 v přednášce 4). Proto řada algoritmů nad stromy je rekurzivních. Zde se zaměříme na binární stromy s tím, že většina algoritmů je zobecnitelná pro k-ární stromy. struct node { int V al; //hodnota uložená v uzlu int Index; //pořadové číslo uzlu node *P arent; //ukazatel na rodiče node *Lef t; //ukazatel na levý podstrom node *Right //ukazatel na pravý podstrom } prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 12 / 22

Rekurzivní algoritmy nad stromy Generování náhodného binárního stromu BS s náhodnou strukturou: náhodně chybějící levé a pravé podstromy. Hodnoty v uzlech jsou náhodná čísla z intervalu [1, 99]. procedure randbintree(h) // h je výška (1){ if (h 0 & Random(1, 2) = 1) (2) then { vygeneruj dynamicky nový uzel N ewn ode; (3) Left[NewNode] randbintree(h 1); (4) V alue[n ewn ode] Random(1, 99); (5) Right[N ewn ode] randbintree(h 1); (6) return(n ewn ode)} (7) else return(null) } 23 47 87 6 3 91 19 36 51 70 prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 13 / 22

Rekurzivní algoritmy nad stromy 3 základní algoritmy procházení stromů a číslování uzlů PreOrder InOrder PostOrder 1 2 3 c 0; //globální čítač uzlů procedure preorderwalk(r) {// r je ukazatel na kořen stromu (1) if (r = Null) then return(); (2) Index[r] c; c c + 1; (3) print(index[r], V alue[r]); (4) preorderwalk(lef t[r]); (5) preorderwalk(right[r]); } 47 87 6 3 19 36 51 70 1 2 3 4 5 6 7 8 9 10 23 47 6 19 36 87 3 51 91 70 23 91 prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 14 / 22

Rekurzivní algoritmy nad stromy 3 základní algoritmy procházení stromů a číslování uzlů PreOrder InOrder PostOrder 2 1 3 c 0; //globální čítač uzlů procedure inorderwalk(r) {// r je ukazatel na kořen stromu (1) if (r = Null) then return(); (2) inorderwalk(lef t[r]); (3) Index[r] c; c c + 1; (4) print(index[r], V alue[r]); (5) inorderwalk(right[r]); } 47 87 6 3 19 36 51 70 1 2 3 4 5 6 7 8 9 10 47 19 6 36 23 51 3 87 70 91 23 91 prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 15 / 22

Rekurzivní algoritmy nad stromy 3 základní algoritmy procházení stromů a číslování uzlů PreOrder InOrder PostOrder 3 1 2 c 0; //globální čítač uzlů procedure postorderwalk(r) {// r je ukazatel na kořen stromu (1) if (r = Null) then return(); (2) postorderwalk(lef t[r]); (3) postorderwalk(right[r]); (4) r.index c; c c + 1; (5) print(index[r], V alue[r]); } 23 47 87 6 3 91 19 36 51 70 1 2 3 4 5 6 7 8 9 10 19 36 6 47 51 3 70 91 87 23 prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 16 / 22

Rekurzivní algoritmy nad stromy Shrnutí Všechny 3 průchody jsou založeny na průchodu do hloubky = DFS (Depth-First-Search). Liší se pouze podmínkou, kdy je procházený uzel označen (zpracován). PreOrder: při první návštěvě. InOrder: při přechodu z levého do pravého podstromu. PostOrder: při poslední návštěvě. PreOrder a PostOrder lze zobecnit pro libovolné k-ární stromy. Binární strom lze tedy linearizovat 3 základními způsoby. Protože v každém souvislém grafu G lze zkonstruovat kostru, lze takto linearizovat (očíslovat) uzly lib. souvislého grafu. prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 17 / 22

Rekurzivní algoritmy nad stromy Velikost a hloubka stromu Algoritmus 6 procedure treesize(r) {// r je ukazatel na kořen stromu (1) if (r = Null) then return(0); (2) return(treesize(lef t[r]) + treesize(right[r]) + 1) } Algoritmus 7 procedure treedepth(r) {// r je ukazatel na kořen stromu (1) if (r = Null) then return(0); (2) return(max(treedepth(lef t[r]), treedepth(right[r])) + 1) } prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 18 / 22

Rekurzivní definované struktury Rekurzivně definované struktury Algoritmus 8 procedure ruler(h) { (1) if (h < 1) (2) then return(); (3) ruler(h 1); (4) print(h); (5) ruler(h 1); } Pokud zavoláme ruler(4), na výstupu se objeví posloupnost čísel v tomto pořadí 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1. prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 19 / 22

Rekurzivní definované struktury Strom rekurzivních volání Koncová volání ruler(0) jsou v obrázku vynechána. ruler(2) ruler(1) print(1) print(2) ruler(1) print(1) ruler(4) ruler(3) print(3) ruler(2) print(4) ruler(2) ruler(3) print(3) ruler(1) print(2) ruler(1) ruler(1) print(2) ruler(1) print(1) print(1) print(1) print(1) ruler(2) ruler(1) print(2) ruler(1) print(1) print(1) prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 20 / 22

Paměťová složitost rekurzivních algoritmů Skutečná paměťová složitost rekurzivních výpočtů V rekurzivní proceduře se při rekurzivním volání téže procedury (totéž pro funkce) musí na systémový zásobník uložit hodnoty parametrů a lokálních proměnných volající procedury. Při návratu po ukončení této vnořené procedury se tyto hodnoty obnoví, aby volající procedura mohla pokračovat se stejným kontextem jako před vstupem do rekurzivního volání. Výška zásobníku se rovná hloubce stromu rekurzivních volání procedury. Rekurzivní výpočet má tedy skrytou paměťovou náročnost úměrnou hloubce tohoto stromu. prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 21 / 22

Paměťová složitost rekurzivních algoritmů Skutečná paměťová složitost rekurzivních algoritmů: Příklad MergeSort (Přednáška 5, Slajd 2): vyžaduje Θ(log n) paměti na zásobník. MS(A,Aux,1,16) MS(A,Aux,1,8) MS(A,Aux,9,16) M(A,Aux,1,16) MS(A,Aux,1,4) MS(A,Aux,5,8) M(A,Aux,1,8) MS(A,Aux,9,12) MS(A,Aux,13,16) M(A,Aux,9,16) MS(A,Aux,1,2) MS(A,Aux,3,4) M(A,Aux,1,4) MS(A,Aux,5,6) MS(A,Aux,7,8) M(A,Aux,5,8) MS(A,Aux,9,10) MS(A,Aux,11,12) M(A,Aux,9,12) MS(A,Aux,13,14) MS(A,Aux,15,16) M(A,Aux,13,16) MS(A,Aux,1,1); MS(A,Aux,2,2) M(A,Aux,1,2) MS(A,Aux,3,3); MS(A,Aux,4,4) M(A,Aux,3,4) MS(A,Aux,5,5); MS(A,Aux,6,6) M(A,Aux,5,6) MS(A,Aux,7,7); MS(A,Aux,8,8) M(A,Aux,7,8) MS(A,Aux,9,9); MS(A,Aux,10,10) M(A,Aux,9,10) MS(A,Aux,11,11); MS(A,Aux,12,12) M(A,Aux,11,12) MS(A,Aux,13,13); MS(A,Aux,14,14) M(A,Aux,13,14) MS(A,Aux,15,15); MS(A,Aux,16,16) M(A,Aux,15,16) prof. Pavel Tvrdík (FIT ČVUT) Rekurzivní algoritmy BI-EFA, 2010, Předn. 8 22 / 22