ABSTRAKTNÍ DATOVÉ TYPY (ADT)

Podobné dokumenty
Datové struktury. alg12 1

Datové struktury. Obsah přednášky: Definice pojmů. Abstraktní datové typy a jejich implementace. Algoritmizace (Y36ALG), Šumperk - 12.

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

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

Konstruktory a destruktory

ADT/ADS = abstraktní datové typy / struktury

Abstraktní datové typy: zásobník

Základní datové struktury

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

Lineární datové struktury

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

V případě jazyka Java bychom abstraktní datový typ Time reprezentující čas mohli definovat pomocí třídy takto:

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

Fronta (Queue) Úvod do programování. Fronta implementace. Fronta implementace pomocí pole 1/4. Fronta implementace pomocí pole 3/4

Kolekce, cyklus foreach

Dynamické datové struktury I.

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

ÚVODNÍ ZNALOSTI. datové struktury. správnost programů. analýza algoritmů

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

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

Úvod do programování - Java. Cvičení č.4

Abstraktní datové typy

Algoritmizace prostorových úloh

Dynamické datové struktury III.

Zásobník (Stack), Fronta (Queue), Kruhový buffer, Spojový seznam, Množina

Šablony, kontejnery a iterátory

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

Lineární datové struktury

Obsah přednášky. 12. Dokumentace zdrojového kódu Tvorba elektronické dokumentace UML. Co je diagram tříd. Ing. Ondřej Guth

Algoritmizace prostorových úloh

10 Generické implementace

Seznamy a iterátory. Kolekce obecně. Rozhraní kolekce. Procházení kolekcí

Šablony, kontejnery a iterátory

Programování II. Návrh programu I 2018/19

Úvod do programovacích jazyků (Java)

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

Generické programování

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

7. Datové typy v Javě

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.

Algoritmizace a programování

Dynamické datové struktury IV.

KTE / ZPE Informační technologie

Výčtový typ strana 67

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

1. Programování proti rozhraní

Úvod do programovacích jazyků (Java)

8 Třídy, objekty, metody, předávání argumentů metod

PREPROCESOR POKRAČOVÁNÍ

Soubor jako posloupnost bytů

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

Paměť počítače. alg2 1

IRAE 07/08 Přednáška č. 2. atr1 atr2. atr1 atr2 -33

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

Programování v Javě I. Leden 2008

Teoretické minimum z PJV

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

Struktura programu v době běhu

Algoritmizace a programování

Programování v Javě I. Únor 2009

1. Téma 12 - Textové soubory a výjimky

Řazení. Uspořádat množinu prvků obsahujících klíč podle definovaného kriteria.

20. Projekt Domácí mediotéka

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

Více o konstruktorech a destruktorech

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

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

int t1, t2, t3, t4, t5, t6, t7, prumer; t1=sys.readint();... t7=sys.readint(); prume pru r = r = ( 1+t 1+t t3+ t3+ t4 t5+ t5+ +t7 +t7 )/ ;

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

9. přednáška - třídy, objekty

7 Formátovaný výstup, třídy, objekty, pole, chyby v programech

prohled av an ı graf u Karel Hor ak, Petr Ryˇsav y 16. bˇrezna 2016 Katedra poˇ c ıtaˇ c u, FEL, ˇ CVUT

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

IRAE 07/08 Přednáška č. 7. Začátek (head)

Seminář z IVT Algoritmizace. Slovanské gymnázium Olomouc Tomáš Kühr

Algoritmizace a programování

III/2 Inovace a zkvalitnění výuky prostřednictvím ICT

Bridge. Známý jako. Účel. Použitelnost. Handle/Body

ADT Seznam. dynamická množina. prvky vkládáme a vyjímáme na libovolné pozici (místě) v jejich posloupnosti (sekvenci) zásobník a fronta vs.

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

Algoritmy a datové struktury

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

TGH07 - Chytré stromové datové struktury

typová konverze typová inference

Třídy, polymorfismus. A0B36PR2-Programování 2 Fakulta elektrotechnická České vysoké učení technické

Abstraktní třída a rozhraní

Základy algoritmizace. Hašování

Datové typy a struktury

Statické proměnné a metody. Tomáš Pitner, upravil Marek Šabo

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

ADT prioritní fronta. Haldy. Další operace nad haldou. Binární halda. Binomické stromy. Časová složitost jednotlivých operací.

Jazyk C++ II. STL knihovna kontejnery část 2

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

Pokročilé programování v jazyce C pro chemiky (C3220) Třídy v C++

Textové soubory. alg9 1

15. Projekt Kalkulačka

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

Abstraktní datové typy FRONTA

IAJCE Přednáška č. 8. double tprumer = (t1 + t2 + t3 + t4 + t5 + t6 + t7) / 7; Console.Write("\nPrumerna teplota je {0}", tprumer);

Seminář Java IV p.1/38

Transkript:

ABSTRAKTNÍ DATOVÉ TYPY (ADT) hierarchie abstrakcí: nejvyšší úroveň ZOO DruhZvirat celá čísla, řetězce nejnižší úroveň bity

Abstrahujeme od - reprezentace (implementace) dat - realizace (implementace) operací nad hodnotami ZOO třída, pole, spojové struktury DruhZvirat - třída celá čísla, řetězce - kódování bity fyzikální jevy

implementace (ZOO.class) - klientský program (ZOOHlavni.class) pracuje s daty jenom metodami ZOO() pridej() tisk()

rozhraní (interface) deklarace používaných metod smlouva mezi klientem a implementací: Klient souhlasí s přístupem k datům pouze použitím metod definovaných rozhraním. Implementace souhlasí s poskytnutím slíbených metod.

ADT je datový typ (množina hodnot a souhrn operací nad nimi) k jehož datům přistupujeme jenom přes rozhraní. Program, který používá ADT - klient Program, který je realizací ADT - implementace Deklarace rozhraní - definice metod signatura (definice) metody = typ návratové hodnoty, jméno metody a typ parametrů V Javě získáme signaturu metody z její deklarace vynecháním jmen formálních parametrů v hlavičce V jazyku Java zabráníme k přístupu členům třídy specifikátorem private

ZOO ADT hlavička: void pridej (String jaky, int kolik) signatura: void pridej (String, int) rozhraní: class ZOO { //ADT ZOO ZOO() void pridej (String, int) void tisk() Kód klienta i implementace ADT jsou nezávislé!!! 1. Můžeme psát klienty před implementací ADT 2. Můžeme měnit implementaci ADT beze změny klienta

Různé implementace mohou mít různé vlastnosti String pridanxtydruh(int) vrátí druh zvířat, který byl do ZOO přidán v pořadí daném parametrem typu int, tj. jako první, druhý, atd. implementace polem String pridanxtydruh (int j) { if (j <= pocet ) return z[j-1].druh; else return "neni tolik druhu"; složitost n stávající počet druhů T(n) = c porovnání + c návratu = c c cf(n) pro f(n) = 1 (n 0 ) a n 0 1 metoda pridanxtydruh v implementaci polem je O(1)

implementace spojovou strukturou String pridanxtydruh(int k) { DruhZvirat x = z; int i = 1; while (x!= null) { if (i == k ) return x.druh; x = x.dalsi; i++; return "neni tolik druhu"; složitost n stávající počet druhů T(n) = 2*c přiřazení + 2*k*c porovnání + 2*(k-1)*c přiřazení + c návratu = 2*k*(c přiřazení + c porovnání ) + c návratu = ak + b metoda pridanxtydruh v implementaci spojovou strukturou je: nejlepší případ k = 1, O(1) nejhorší případ k = n, O(n) průměrný případ k = n/2, O(n)

Dynamické množiny [Cormen et al.] V matematice množina jako souhrn nějakých prvků je po její specifikaci neměnná. Dynamická množina - souhrn prvků, který se může zvětšovat, zmenšovat nebo jinak měnit. Dvě základní operace vlož prvek vyber prvek Jednotlivé prvky jsou identifikovány hodnotou položky klíč - druh pro prvky DruhZvirat Další typickou operací nad dynamickými množinami potom může být operace najdi prvek, kterého klíč má zadanou hodnotu

ADT ZÁSOBNÍK A FRONTA STACK and QUEUE Operace vyber ze zásobníku vyjme prvek, který byl operací vlož do zásobníku vložen jako poslední. last-in, first-out LIFO Operace vyber z fronty vyjme prvek, který je ve frontě vložený nejdéle, jinými slovy z prvků, které jsou ve frontě vybere ten, který byl do fronty vložen jako první. first-in, first-out FIFO Obě tyto ADT jsou používány mnoha algoritmy (klienty) na dalších úrovních abstrakce. Implementace: - polem - spojovou strukturou

Zásobník JVM je zásobníkový stroj - ukázali jsme si jeho použití na vyhodnocování výrazů. Zpracování řádky textu na obrazovce píšeme = přidáváme znak na konec řádky mažeme - backspace = odebereme poslední napsaný znak Vyvážené použití závorek { a v deklaraci třídy 1.Čti znaky textu. 2. Je-li znakem otevírací závorka, vlož ji do zásobníku. 3. Je-li přečtený znak zavírací závorka, je-li zásobník prázdný ohlas chybu chybějící otvírací závorka, jinak vyber prvek ze zásobníku. 4. Jsou-li přečteny všechny znaky, je-li zásobník prázdný závorky jsou vyváženy, jinak ohlaš chybu chybějící zavírací závorka.

vlož - push vyber - pop Implementace zásobníku celých čísel třída IntZasobnik class IntZasobnik { // ADT rozhrani IntZasobnik() // vytvoření prázdného zásobníku boolean jeprazdny() // test je-li prázdný void push(int) // vložení prvku int pop() // výběr prvku http://www.cs.usask.ca/resources/tutorials/csconcepts/index.html

Implementace pomocí pole class IntZasobnik { private int[] z; private int vrchol; final int maxn=10; IntZasobnik() { z = new int[maxn]; vrchol = 0; boolean jeprazdny() { return (vrchol == 0); void push(int klic) { z[vrchol++] = klic; int pop() { return z[--vrchol];

Čas každé z operací nad zásobníkem implementovaným pomocí pole je O(1). Vykonání operace pop nad prázdným zásobníkem - podtečení underflow zásobníku. V Javě lze na něj reagovat použitím mechanizmu výjimek. Vykonání operace push (vrchol = maxn) - přetečení overflow zásobníku. Velikost vytvářeného zásobníku - parametr konstruktoru. private int[] z; private int vrchol; IntZasobnik(int maxn) { z = new int[maxn]; vrchol = 0;

Technika dynamického rozšiřování pole class DynPole { public static void main (String[] arg) { int maxn = 4; int n; int[] a = new int[maxn]; for(n = 0; n < a.length; n++) a[n] = n; int[] x = a; a = new int[2*a.length]; for(n = 0; n < x.length; n++) a[n] = x[n]; for(n = maxn; n < a.length; n++) a[n] = n; for(n=0; n < a.length; n++) System.out.println(n);

Čas vkládání při použití dynamického pole agregovaná analýza čas vyjádříme počtem přiřazení při vkládání i-tého prvku c i (začínáme s polem velikosti 1) je-li pole plné, obsahuje i -1 prvků, i 1 = 2 j, j=0,1,2,... přiřadíme jeho prvky do nového pole a přiřadíme vkládanou i-tou hodnotu c i = i jinak, přiřadíme vkládanou i-tou hodnotu c i = 1 amortizovaná analýza průměrný čas operace pro posloupnost n vykonaných operací pole bylo plné log 2 n krát průměrný čas operace n log 2 n 1/n c i 1/n (n + 2 j ) < 1/n (n + 2n) = 3 i=1 j=0 operace vkládání (push) je tedy O(1)

účtovací metoda - cena (čas) přímého vložení (přiřazení) nechť je 1$ - mějme pole o velikosti 2m v okamžiku jeho rozšíření - obsahuje m vložených prvků a m volných pozic - přímé vložení dalších m prvků stojí m$ - před dalším rozšířením musíme kopírovat (vložit do nového rošířeného pole) 2m prvků, což stojí 2m$ - cena vložení dalších m prvků je m$ + 2m$ = 3m$

Implementace zásobníku spojovým seznamem class IntZasobnik { private Prvek vrchol; private class Prvek { int klic; Prvek dalsi; Prvek (int klic, Prvek dalsi) { this.klic = klic; this.dalsi = dalsi; IntZasobnik() { vrchol = null; boolean jeprazdny() { return (vrchol == null); void push(int klic) { vrchol = new Prvek(klic, vrchol); int pop() { int v = vrchol.klic; vrchol = vrchol.dalsi; return v;

Čas každé z operací nad zásobníkem implementovaným pomocí spojového seznamu je O(1). Implementace ADT IntZasobnik můžeme zaměnit bez jakékoliv změny klientského programu. class Zasobnik { public static void main(string[] arg) { IntZasobnik Zasobnik = new IntZasobnik(); if (Zasobnik.jePrazdny()) System.out.println("zasobnik je prazdny"); Zasobnik.push(4); System.out.println(Zasobnik.pop()); if (Zasobnik.jePrazdny()) System.out.println("zasobnik je prazdny"); Zasobnik.push(4); Zasobnik.push(3); Zasobnik.push(2); Zasobnik.push(1); System.out.println(Zasobnik.pop()); System.out.println(Zasobnik.pop()); System.out.println(Zasobnik.pop()); System.out.println(Zasobnik.pop());

Zásobník objektů rozhraní: class ObjZasobnik { //ADT rozhrani ObjZasobnik() boolean jeprazdny() void push(objekt) Objekt pop() class Objekt {...

class ObjZasobnik { private Prvek vrchol; private class Prvek { Objekt ref; Prvek dalsi; Prvek (Objekt ref, Prvek dalsi) { this.ref = ref; this.dalsi = dalsi; ObjZasobnik() { vrchol = null; boolean jeprazdny() { return (vrchol == null); void push(objekt ref) { vrchol = new Prvek(ref, vrchol); Objekt pop() { Objekt r = vrchol.ref; vrchol = vrchol.dalsi; return r;

Méně vhodné řešení je rozšířit ukládaný objekt o členskou proměnnou dalsi (jako DruhZvirat), protože vyžaduje zásah do deklarace třídy ukládaných objektů. Porovnání implementací Implementace pomocí pole - vyžaduje po celou dobu výpočtu paměť pro předpokládaný maximální počet prvků (pokud neuvažujeme dynamické pole) Implementace pomocí spojového seznamu - vyžaduje paměťový prostor úměrný počtu uložených prvků - potřebuje paměť pro uchovávání ukazatelů a čas na přidělení paměti při každé operaci push a nakonec čas na uvolnění paměti po každé operaci pop. http://java.sun.com/j2se/1.5.0/docs/api/java/util/stack.html

Fronta Fronta je reprezentací každodenních situacích v bance, jídelně, šatně ap. Často je využívána v operačních systémech Rozhraní class IntFronta { // ADT rozhrani IntFronta() // vytvoření prázdné fronty boolean jeprazdna() // test je-li prázdná void vloz(int) // vložení prvku int vyber() // výběr prvku

Implementace fronty pomocí pole - neposouváme ukládané prvky v poli - udržujeme hodnoty dvou indexů zacatek index odkud vybereme prvek konec index kam uložíme prvek zacatek = 0; konec = 0; po uložení prvku na konec: konec++; konec = konec % maxn; po uložení maxn-tého prvku na index maxn 1: konec == 0; V případě, že fronta je prázdná nebo plná jsou si tyto indexy rovny! Vytvoříme pole pro implementaci fronty o 1 větší než maximální počet prvků fronty a rovnost indexů bude znamenat prázdné pole.

class IntFronta { private int[] f; private int zacatek, konec; final int maxn=5, n; IntFronta() { n = maxn + 1; f = new int[n]; zacatek = 0; konec = 0; boolean jeprazdna() { return (zacatek == konec); void vloz(int klic) { f[konec++] = klic; konec = konec % n; int vyber() { int v = f[zacatek++]; zacatek = zacatek % n; return v;

Čas každé z operací nad frontou implementovanou pomocí pole je O(1). Alternativa můžeme použít proměnnou pro počet prvků ve frontě, která se inkrementuje v operaci vloz a dekrementuje v operaci vyber a podle její hodnoty určit, je-li fronta prázdná nebo plná.

Implementace fronty pomocí spojového seznamu Použijeme ukazatel na konec seznamu, kam prvky vkládáme a ukazatel na začátek, odkud prvky vybíráme. class IntFronta { private class Prvek { int klic; Prvek dalsi; Prvek(int klic) { this.klic = klic; this.dalsi = null; private Prvek zacatek, konec; IntFronta() { zacatek = null; konec = null; boolean jeprazdna() { return (zacatek == null); void vloz(int klic) { Prvek k = konec; //ulozime konec pred vloz konec = new Prvek(klic); if (jeprazdna()) zacatek = konec; else k.dalsi = konec;

int vyber() { int v = zacatek.klic; zacatek = zacatek.dalsi; return v; Čas každé z operací nad frontou implementovanou pomocí spojového seznamu je O(1). Porovnání implementací stejné jako pro zásobník http://www.cs.usask.ca/resources/tutorials/csconcepts/index.html http://java.sun.com/j2se/1.5.0/docs/api/java/util/queue.html

class Fronta { public static void main(string [] arg) { IntFronta fronta = new IntFronta(); if (fronta.jeprazdna()) System.out.println("fronta je prazdna"); fronta.vloz(4); System.out.println(fronta.vyber()); if (fronta.jeprazdna()) System.out.println("fronta je prazdna"); fronta.vloz(1); fronta.vloz(2); fronta.vloz(3); fronta.vloz(4); fronta.vloz(5); System.out.println(fronta.vyber()); System.out.println(fronta.vyber()); System.out.println(fronta.vyber()); System.out.println(fronta.vyber()); System.out.println(fronta.vyber()); if (fronta.jeprazdna()) System.out.println("fronta je prazdna");

http://www.kiv.zcu.cz/~netrvalo/vyuka/ppa2/portal/cviceni/cv04.pdf