Anotace. Pointery, dynamické proměnné



Podobné dokumenty
Anotace. Pointery. Martin Pergel,

NMIN102 Programování /2 Z, Zk

Anotace. Objekt self, Zapouzdření, polymorfismus,

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

Anotace. Soubory a práce s nimi, rekurze podruhé, struktury (datový typ record), Martin Pergel,

Anotace. Informace o praktiku z programování!!! Direktivy překladače Soubory (textové) Quicksort Metoda rozděl a panuj

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

Digitální učební materiál

Programovací jazyk Pascal

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

Anotace. Spojové seznamy, haldy. AVL-stromy, A-B stromy. Martin Pergel,

Obecná informatika. Matematicko-fyzikální fakulta Univerzity Karlovy v Praze. Podzim 2012

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

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

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

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

Je n O(n 2 )? Je n 2 O(n)? Je 3n 5 +2n Θ(n 5 )? Je n 1000 O(2 n )? Je 2 n O(n 2000 )? Cvičení s kartami aneb jak rychle roste exponenciála.

Anotace. Dynamické programování, diskrétní simulace.

Prioritní fronta, halda

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

Anotace. Ordinalni typy - typ char, funkce ord, chr, succ, prev, inc, dec,

Maturitní témata. IKT, školní rok 2017/18. 1 Struktura osobního počítače. 2 Operační systém. 3 Uživatelský software.

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

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

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

Anotace. pointery (pars prima). Martin Pergel,

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

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

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

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

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

Úvod do programování

Dynamické datové typy a struktury

Časová a prostorová složitost algoritmů

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

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

3 Co je algoritmus? Trocha historie Definice algoritmu Vlastnosti algoritmu... 3

Správa paměti. Karel Richta a kol. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze Karel Richta, 2016

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

Další možnosti inicializace proměnných

Operační systémy. Jednoduché stránkování. Virtuální paměť. Příklad: jednoduché stránkování. Virtuální paměť se stránkování. Memory Management Unit

Závěrečná zkouška z informatiky 2011

Správa paměti. doc. Ing. Miroslav Beneš, Ph.D. katedra informatiky FEI VŠB-TUO A-1007 /

Rekurze a rychlé třídění

Definice funkcí a procedur. Mnoho operací provozujeme opakovaně, proto je hloupé programovat je při každém použití znovu.

Programování 2 (NMIN102) Soubory. RNDr. Michal Žemlička, Ph.D.

Michal Krátký. Úvod do programování. Cíl kurzu. Podmínky získání zápočtu III/III

Více o konstruktorech a destruktorech

2. Složitost, grafové algoritmy (zapsal Martin Koutecký)

Struktura programu v době běhu

Objektově orientované programování

Vysvětlete funkci a popište parametry jednotlivých komponent počítače a periferních zařízení.

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

13. Třídící algoritmy a násobení matic

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

Základní způsoby: -Statické (přidělění paměti v čase překladu) -Dynamické (přiděleno v run time) v zásobníku na haldě

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

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

Anotace. Dijkstrův algoritmus,

Algoritmizace řazení Bubble Sort

Složitost algoritmů. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava

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

Inovace a zkvalitnění výuky prostřednictvím ICT Základy programování a algoritmizace úloh Třídění dat. Ing. Hodál Jaroslav, Ph.D. VY_32_INOVACE_26 04

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

Složitost Filip Hlásek

Abstraktní datové typy FRONTA

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

Digitální učební materiál

Digitální učební materiál

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

Rekurzivní algoritmy

Inovace a zkvalitnění výuky prostřednictvím ICT Základy programování a algoritmizace úloh Typové a netypové soubory

Sdílení dat mezi podprogramy

Cvičení 5 - Inverzní matice

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

Přednáška. Správa paměti II. Katedra počítačových systémů FIT, České vysoké učení technické v Praze Jan Trdlička, 2012

Akademický rok: 2004/05 Datum: Příjmení: Křestní jméno: Osobní číslo: Obor:

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

Zpracoval: 7. Matematická indukce a rekurse. Řešení rekurentních (diferenčních) rovnic s konstantními koeficienty.

Dynamické datové struktury III.

Mimo samotné správnosti výsledku vypočteného zapsaným algoritmem je ještě jedno

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

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

Dynamické datové struktury IV.

Vzdělávací oblast: Informatika a informační a komunikační technologie Vzdělávací obor: Programování. Předmět: Programování

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

Ukazatele, dynamická alokace

Kolekce ArrayList. Deklarace proměnných. Import. Vytvoření prázdné kolekce. napsal Pajclín

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

Zpracování deklarací a přidělování paměti

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.

Př. další použití pointerů

Správné vytvoření a otevření textového souboru pro čtení a zápis představuje

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

O datových typech a jejich kontrole

dovolují dělení velkých úloh na menší = dekompozice

Algoritmizace složitost rekurzivních algoritmů. Jiří Vyskočil, Marko Genyg-Berezovskyj 2010

- dělají se také pomocí #define - podobné (použitím) funkcím - předpřipravená jsou např. v ctype.h. - jak na vlastní makro:

1 PRVOCISLA: KRATKY UKAZKOVY PRIKLAD NA DEMONSTRACI BALIKU WEB 1

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

Transkript:

Anotace Třídění, Pointery, dynamické proměnné

Radix- alias bucketsort Třídíme-li celá (přirozená) čísla, jejichž velikost je omezena, můžeme využít toho, že v desítkovém zápisu je na každé pozici jen jedna číslice z deseti. Můžeme tedy čísla rozhodit na hromádky podle těchto číslic. Naivní algoritmus by zřejmě začal od začátku, vytřídil nejmenší a jel dále. To by sice fungovalo, ale bylo by to ošklivé. My začneme od poslední číslice.

Bucketsort Pozor, kreativní pseudokód! procedure bucketsort(pole); begin for i:=0 to delka do begin rozhod cisla z pole do pole0 az pole9; podle cislice na i-tem miste; pole:=pole0+pole1+pole2+...+pole9; end; end;

Bucketsort analýza Složitost: delka je konstanta, tedy konstantně-krát prolezeme pole délky n, tudíž složitost je Θ(n) (dolní odhad opět triviálně n, na každý prvek musíme kouknout ). Korektnost: Pokud se dvě čísla liší, liší se na nějaké pozici. Uvažme nejvyšší řád, na kterém se liší. Na tomto řádu má menší číslo menší číslici a tudíž: při rozhazování podle tohoto řádu se menší číslo dostane před větší. Dále jdou čísla do stejné přihrádky a tudíž se jejich pořadí nemění. Co je s naším dolním odhadem Ω(n log n)? Nemá splněné předpoklady, bucketsort čísla vůbec neporovnává.

Paměti Počítače mají několik typů pamětí: Operační (zpravidla RAM), persistentní (disky, diskety, magnetofonové pásky, děrné štítky). Prvním občas říkáme vnitřní, druhým vnější. Vnitřní paměť je rychlá, kdežto vnější paměť je velká. Ve vnitřní paměti můžeme dovádět, ve vnější paměti hledání trvá déle (je vhodné načíst údaje za sebou, ne hledat po celé paměti). Naše třídicí algoritmy jsou určitě vhodné pro vnitřní paměť (obzvlášť heapsort, který nepotřebuje paměť navíc, ale s haldou nevybíravě otřásá). Pro vnější paměti je vhodný mergesort.

Vnější třídění Načti co největší blok do operační paměti, sestav haldu a při extract-min místo zakořenění posledního zkus načíst další prvek. Je-li tento prvek aspoň tak velký jako poslední prvek, co jsme poslali na výstup, zabublej ho. Je-li tento prvek menší než poslední prvek, co jsme poslali na výstup, nepřidávej ho do haldy, dokonči nad haldou heapsort a založ novou haldu. Takto získáme v mezích možností dlouhé setříděné bloky, na které můžeme pustit mergesort.

Vnější třídění s více páskami Dnes pro praktické použití už asi passé, ale: Stává se, že máme k dispozici pásek více (dnes třeba disků). Pak je výhodou mergovat ze všech ostatních na jednu. Na každé pásce ovšem máme několik bloků. Dojde-li obsah jedné pásky, doběhneme současné mergované bloky a začneme mergovat na uvolněnou pásku. Jak zorganizovat počty bloků na jednotlivých páskách? Zobecněnými Fibonacciho čísly.

Organizace počtu bloků pro mergesort Předpokládejme, že máme tři pásky. Chceme, aby slévání skončilo jedním dlouhým blokem na jedné pásce : (0,0,1) Tudíž předtím na ostatních dvou páskách muselo být po jednom bloku: (1,1,0) Bezprostředně předtím jsme mergovali ze třetí pásky (protože se vyprázdnila) a museli jsme mergovat někam (BÚNO na druhou). Tedy předtím vypadalo rozmístění bloků takto: (2,0,1)

Předtím tudíž výpočet vypadal takto: (0,2,3) Předtím zase takto: (3,5,0)... Tedy vždy jde o dvě po sobě jdoucí Fibonacciho čísla (a třetí je nula). Vychází totiž rekurence a n = a n 1 + a n 2, obecně a n = a n 1 +... + a n k.

K čemu jsou dynamické proměnné? K mnoha algoritmům bychom potřebovali pole proměnlivé délky nebo aspoň jinou datovou strukturu proměnlivé délky. Jak implementovat frontu a zásobník? Použijeme pointery.

Pointery alias ukazatele Paměť je organizována lineárně v podobě jednotlivých adres. Na těchto adresách jsou ukládány hodnoty (kód, data). Paměť zpravidla adresujeme přirozenými čísly, která zapisujeme v šestnáctkové soustavě. Na data v paměti si tedy můžeme ukazovat. Pod těmito ukazateli můžeme mít údaje libovolných typů, z čehož vyplývá jisté nebezpečí. Z toho vzplývá jisté nebezpečí a nutnost být obezřetný.

Pointery syntax a sémantika S pointery pracujeme zpravidla tak, že definujeme datový typ ukazatel na něco. Ukazatel na řekneme pomocí operátoru stříšky: type pint=^integer; {ukazatel na integer} Následně definujeme proměnnou příslušného typu: var ukaz:pint; Pod pointer koukneme opět pomocí operátoru stříšky: writeln(ukaz^); Jenže ono to zdaleka není tak snadné!

Organizace paměti s ohledem na program Program sestává z kódu, tzv. statických dat, prostoru zásobníku a oblasti haldy. Kam ukazuje pointer, který si lehkomyslně vyrobíme? Pokud s ním budeme zacházet rozumně, bude ukazovat někam do oblasti haldy, k tomu ale máme ještě daleko. Kam tedy pointer ukazuje? V lepším případě na adresu 0, v horším na náhodně vybraný kus paměti. Pořádek v paměti hlídá allokátor, který ví, které části paměti jsou použité a které ne a může nám přidělit prostor.

Allokátor a jeho použití Abychom mohli pod pointer kouknout, musíme ho někam nasměrovat. A to buďto na už existující pointer (var a,b:pint;... naalokuj b;... a:=b;), anebo urafnutím nové paměti: new(a); Funkci new předáváme jako parametr proměnnou typu ukazatel. Funkce new najde v paměti vhodné místo a nasměruje na něj příslušný pointer. Cvičení zimního učiva: Bere new parametr hodnotou nebo referencí? Od chvíle, kdy máme naalokováno, můžeme pod pointer koukat i zapisovat: new(a); a^:=5; writeln(a^); Ale pozor na přesměrování ukazatele!

Pointery a práce s nimi var a,b:pint; new(a); naallokuje místo pro proměnnou typu integer a^:=5; zapíše pod pointer hodnotu 5. b^:=a^; okopíruje pod pointer b hodnotu, na kterou ukazuje pointer a. b:=a; okopíruje pointer (tedy a a b ukazují na stejné místo). Co v kontextu uvedeného kódu udělá b^:=10; writeln(a^);? Pozor, více pointery si můžeme ukazovat na to samé místo!

Deallokace Nepotřebujeme-li už příslušné místo, musíme to říci allokátoru voláním funkce dispose: dispose(a); Tím prohlásíme, že pod dotyčný pointer už nepotřebujeme. Pozor pokud si na totéž místo ukazujeme víckrát, nesmíme provést vícenásobné odallokování! Pokud pointer přesměrujeme bez odallokování (ničím si na dotyčné místo neukazujeme), vzniká tzv. garbage, o které má allokátor za to, že je používaná, my však už nemáme, jak se k dotyčnému kusu paměti dostat (tak ho nemůžeme ani odallokovat). Některé jazyky (Java, C#) takto odallokovávají (přestaneme si na kus paměti ukazovat). Říká se tomu garbage collector, je to nevýchovné a v Pascalu není implementován.

Typičtější použití pointerů V zimě jsme se učili o strukturách (records). Struktury nám umožňovaly udržovat údaje různých typů spolu souvisejících. Například dvě souřadnice bodu v rovině, údaje o lidech, údaje o knihách... Do recordu se přistupuje operátorem tečky. Typicky se dělají pointery na struktury: Příklad: type tbod=record x,y:integer; end; pbod=^tbod; Stále ještě neřešíme původní problém, co když máme bodů víc a nevíme předem kolik?

Přivřeme do struktury ukazatel na další prvek: type pbod=^tbod; tbod=record x,y:integer; next:pbod; end; Tomu říkáme spojový seznam. Jak poznáme, který ukazatel někam ukazuje? Tak, že nepoužitý pointer okamžitě nasměrujeme na nulu, tedy nil.

Spojový seznam čísel načti a vypiš Příklad datové struktury type pint=^sint; sint=record cislo:integer; next:pint; end; var spojak,pom:pint;

Spojový seznam čísel načti a vypiš Příklad tělo kódu begin spojak:=nil; pom:=nil; while not EOF do begin new(pom); readln(pom^.cislo); pom^.next:=spojak; spojak:=pom; end; while spojak<>nil do begin writeln(spojak^.cislo); pom=spojak; spojak=spojak^.next; dispose(pom); end; end.