Abstraktní datové typy

Podobné dokumenty
Mělká a hluboká kopie

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

Pole, množina, tabulka

Základní datové struktury

Abstraktní třídy, polymorfní struktury

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

Konstruktory a destruktory

Šablony, kontejnery a iterátory

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

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

Šablony, kontejnery a iterátory

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

Datové struktury. alg12 1

Lineární datové struktury

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

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.

Dynamické datové struktury I.

Algoritmizace prostorových úloh

Přetěžování operátorů

Abstraktní datové typy: zásobník

Kolekce, cyklus foreach

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

Další příklady. Katedra softwarového inženýrství. Katedra teoretické informatiky, Fakulta informačních technologii, ČVUT v Praze. Karel Müller, 2011

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

Jazyk C++, některá rozšíření oproti C

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

Algoritmizace prostorových úloh

ADT/ADS = abstraktní datové typy / struktury

Lineární datové struktury

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

Spojové struktury. Jan Faigl. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze. Přednáška 10 A0B36PR1 Programování 1

Dynamické datové struktury IV.

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

Část I Spojové struktury

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

Abstraktní datové typy

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

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

PREPROCESOR POKRAČOVÁNÍ

Datové struktury 2: Rozptylovací tabulky

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

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

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

ABSTRAKTNÍ DATOVÉ TYPY (ADT)

Objektov orientované programování. C++ Akademie SH. 7. Objektov orientované programování. Michal Kvasni ka. Za áte níci C++ 2.

Definice uživatelského typu. Uživatelem definované typy. Součinové datové typy. Součtové datové typy. FLP - Uživatelem definované typy

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

PB161 Programování v jazyce C++ Přednáška 3

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

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

Dynamické struktury a Abstraktní Datový Typy (ADT)

Část 1 Spojové struktury (stromy) Dynamické struktury a Abstraktní Datový Typy (ADT) Část 2 Abstraktní datový typ. Část 3 Příklad ADT Prioritní fronta

OBJEKTOVÉ PROGRAMOVÁNÍ V C++ V PŘÍKLADECH 8 Proudová knihovna 8.1 Hierarchie proudů Standardně zavedené proudy

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

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

Pokročilé programování v jazyce C pro chemiky (C3220) Statické proměnné a metody, šablony v C++

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

Jazyk C++ I. Šablony

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

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

Dynamické datové struktury III.

KTE / ZPE Informační technologie

PB přednáška (26. října 2015)

Návrhové vzory. Jakub Klemsa, Jan Legerský. 30. října Objektově orientované 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)

Spojový seznam. Jan Kybic.

ALG 04. Zásobník Fronta Operace Enqueue, Dequeue, Front, Empty... Cyklická implementace fronty. Průchod stromem do šířky

Základy algoritmizace. Hašování

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

Jazyk C# (seminář 6)

Šablony funkcí a tříd (Templates) Genericita

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

Jazyk C++ I. Šablony 2

Více o konstruktorech a destruktorech

Iterátory v C++. int pole[20]; for (int *temp = pole, temp!= &pole[20]; temp++) { *temp = 0;

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

PB161 Programování v C++ Proudy pro standardní zařízení Souborové proudy Paměťové proudy Manipulátory

Dynamika objektů. Karel Richta a kol. katedra počítačů FEL ČVUT v Praze

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

Zadání k 2. programovacímu testu

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

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

Algoritmizace a programování

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

Datové struktury obsah přednášky 1. Úvod 2. Třídy Type-wrapper (obalový typ) pro primitivní typy automatické převody 3. Automatické převody mezi

Úvod do programovacích jazyků (Java)

PB161 Programování v jazyce C++ Přednáška 4

Vector datový kontejner v C++.

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

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

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

IB111 Programování a algoritmizace. Objektově orientované programování (OOP)

Dědění, polymorfismus

boolean hasnext() Object next() void remove() Kolekce

PB161 Programování v jazyce C++ Přednáška 3

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

Rekurzivní algoritmy

Jazyk C++ II. Šablony a implementace

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

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

Transkript:

Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 1/27 Abstraktní datové typy Ing. Josef Vogel, CSc Katedra softwarového inženýrství Katedra teoretické informatiky, Fakulta informačních technologii, ČVUT v Praze Karel Müller, Josef Vogel, 2011 Programování a algoritmizace 2, BI-PA2, 2011, Přednáška 10 BI-PA2 Evropský sociální fond Praha & EU: Investujeme do vaší budoucnosti

Abstraktní datové typy Připomeňme: Abstraktní datový typ specifikuje množinu hodnot a množinu operací nezávisle na implementaci ADT lze specifikovat formálně pomocí signatury operací (syntaxe) a axiomů, které udávají sémantiku operací (viz 7. přednáška) ADT lze méně formálně specifikovat pomocí signatury a slovního popisu sémantiky operací V C++ ADT realizujeme pomocí třídy, větší použitelnost má realizace pomocí šablony třídy Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 2/27

Kontejnery Kontejner (kolekce) je ADT na organizované skladování prvků podle určitých pravidel Sekvenční kontejnery různě organizované sekvence Zásobník (Stack) Fronta (Queue) Seznam (List) Pole (Array, Vector, Matrix,...) umožňuje náhodný přístup k prvkům Množina (Set) Asociativní kontejnery pro vkládání, odebírání a vyhledávání je důležitý klíč prvku Tabulka (Table, Map) V C++ realizujeme ADT kontejneru buď mocí třídy s daným typem prvků, nebo pomocí šablony třídy, kde typ prvků je parametrem šablony Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 3/27

ADT Zásobník Připomenutí: zásobník je kontejner, kde vkládání a odebírání prvků probíhá na stejném konci zvaném vrchol zásobníku (LIFO) Šablona: template <class T> class Stack { public: Stack(); bool empty() const; void push(const T& x); T top() const; void pop(); private:... ; Poznámka: operace top a pop bývají často spojeny do jediné: T pop(); Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 4/27

ADT Zásobník Implementace zásobníku: pomocí pole, jehož počet prvků je dán konstantou (počet prvků zásobníku je staticky omezen) pomocí dynamicky alokovaného pole, jehož počet prvků je dán parametrem konstruktoru (počet prvků zásobníku je dynamicky omezen) pomocí dynamicky alokovaného a rozšiřitelného pole pomocí jednosměrného spojového seznamu Složitost všech operací je konstantní, výjimkou je vkládání do zásobníku realizovaného pomocí rozšiřitelného pole; pokud se pole rozšiřuje vždy na dvojnásobnou délku, je složitost vkládání téměř konstantní Podrobnosti viz příklady k přednášce 7 Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 5/27

ADT Fronta Připomenutí: fronta je kontejner, kde se vkládá na konec a odebírá z čela (FIFO) Šablona: template <class T> class Queue { public: Queue(); bool empty() const; void add(const T& x); T front() const; void remove(); private:... ; Poznámka: operace front a remove bývají často spojeny do jediné: T remove(); Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 6/27

ADT Fronta Implementace fronty: pomocí pole, jehož počet prvků je dán konstantou (počet prvků fronty je staticky omezen) pomocí dynamicky alokovaného pole, jehož počet prvků je dán parametrem konstruktoru (počet prvků fronty je dynamicky omezen) pomocí dynamicky alokovaného a rozšiřitelného pole pomocí jednosměrného spojového seznamu Od implementace se očekává, že složitost všech operací bude konstantní (s výjimkou vkládání do rozšiřitelného pole, které se řeší podobně jako v případě zásobníku) Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 7/27

p10\queue1\queue1.h Implementace fronty Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 8/27 Pomocí pole se staticky daným počtem prvků celo volny pocet pole 0 celo volny M-1 class Queue { public: //enum {M = 40; static const int M=40; // tak to jde take Queue(); void add(const T&); T front() const; void remove(); bool empty() const; private: int celo, volny, pocet; T pole[m]; ;

p10\queue2\queue2.h Implementace fronty Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 9/27 Pomocí pole s dynamicky daným počtem prvků celo volny pocet M 0 celo volny M-1 pole class Queue { public: Queue(int = 40); ~Queue(); void add(const T&); T front() const; void remove(); bool empty() const; private: int celo, volny, pocet; int M; T* pole; Queue(const Queue&); Queue& operator=(const Queue&); ;

p10\queue3\array.h Implementace fronty Pomocí rozšiřitelného pole Připomeňme šablonu třídy Array pro rozšiřitelné pole template <class Elem> class Array { public: Array(int=10); Array(const Array&); ~Array(); int length() const {return len; Elem& operator[](int); const Elem& operator[](int) const; Array& operator=(const Array&); void extend(int); private: Elem* array; int len; void copy(const Array&); ; Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 10/27

p10\queue3\queue3.h Implementace fronty Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 11/27 Pomocí rozšiřitelného pole (instance šablony třídy Array) celo volny pocet pole 0 celo volny len-1 class Queue { public: Queue(); bool empty() const {return pocet==0; void add(const T&); T front() const; void remove(); private: int celo; int volny; int pocet; Array<T> pole; ;

p10\queue4\queue4.h Implementace fronty Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 12/27 Pomocí spojového seznamu celo volny class Queue { public: Queue(); ~Queue(); void add(const T&); T front() const; void remove(); bool empty() const; private: struct Item { T val; Item *next; Item() {next = NULL; ; Item *celo, *volny; Queue(const Queue&); Queue& operator=(const Queue&); ;...

ADT Seznam Seznam je sekvenční kontejner, pro který operace vložení, odebrání a čtení se provádějí na označené pozici, kterou lze měnit Příkladem seznamu je text zobrazený v okně Poznámkové bloku: pozice je dána umístěním kurzoru stiskem klávesy vložíme znak před kurzor klávesou Del vyjmeme znak označný kurzorem klávesou Backspace vyjmeme znak před kurzorem klávesou resp. přesuneme kurzor na předchozí resp. následující znak klávesou Home resp. End přesunem kurzor na začátek resp. konec textu Vyzkoušejme... Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 13/27

Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 14/27 ADT Seznam Signatura operací nad seznamem (T je typ hodnot v seznamu): init: -> List insert(_,_): List,T -> List remove(_): List -> List removeprev(_): List -> List tonext(_): List -> List toprev(_): List -> List tobegin(_): List -> List toend(_): List -> List empty(_): List -> bool atbegin(_): List -> bool atend(_): List -> bool read(_): List -> T prázdný seznam vlož před kurzor odeber odeber před kurzorem kurzor na další kurzor na předchozí kurzor na začátek kurzor na konec je seznam prázdný? je kurzor na začátku? je kurzor na konci? hodnota na kurzoru

p10\list\list.h Třída List Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 15/27 class List { public: List(); ~List(); void insert(t); // vloz pred kurzor void remove(); // odstran prvek na kurzoru void removeprev(); // odstran prvek pred kurzorem void tonext(); // kurzor na dalsi prvek void toprev(); // kurzor na predchozi prvek void tobegin(); // kurzor na zacatek void toend(); // kurzor na konec bool empty(); // je seznam prazdny? bool atbegin(); // je kurzor na zacatku? bool atend(); // je kurzor na konci bool read(t&); // cteni z pozice kurzoru friend ostream& operator<<(ostream&, const List&); private:... ;

Třída List Sémantiku operací si upřesníme na příkladech Příklad výpisu seznamu: seznam obsahující hodnoty x, y a z, kde na pozici kurzoru je y, vypíšeme ve tvaru [x y z] Budeme uvažovat seznam celých čísel List szn; [ ] szn.insert(10); [10 ] szn.insert(20); [10 20 ] szn.toprev(); [10 20] szn.insert(30); [10 30 20] szn.tonext(); [10 30 20 ] szn.tobegin(); [ 10 30 20] szn.toend(); [10 30 20 ] szn.remove(); [10 30 20 ] szn.removeprev(); [10 30 ] szn.toprev(); [10 30] szn.remove() [10 ]... Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 16/27

Jakou datovou strukturu použít pro implementaci? Chceme, aby všechny operace měly konstantní složitost Tento požadavek nesplňuje použítí pole, kde při vkládání jinam než na konec by bylo třeba posouvat prvky pole (lineární složitost), podobně při odebírání Použijeme proto spojový seznam Objekt bude obsahovat ukazatel na první prvek a dále ukazatel na prvek označený kurzorem Aby operace kurzor na předchozí prvek měla konstantní složitost, použijeme dvojsměrný spojový seznam Aby operace kurzor na konec měla konstantní složitost, bude objekt obsahovat též ukazatel na konec seznamu Aby kurzor ukazující na konec seznamu bylo možné posunout na předchozí prvek, bude koncem seznamu poslední prvek spojového seznamu, ve kterém nebude žádná hodnota Grafické znázornění vnitřní reprezentace na dalším slajdu Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 17/27

Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 18/27 Implementace dvojsměrným spojovým seznamem Příklady seznamů a jejich vnitřní reprezentace [ ] begin tail mark [10 ] begin tail mark 10 [10 20] begin tail mark 10 20 [ 10 20] begin tail mark 10 20

p10\list\list.h Privátní část třídy List Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 19/27 private: struct Node { T val; Node *next, *prev; Node(T x, Node *n) { // n nesmi byt NULL val = x; next = n; prev = n->prev; Node() {next = NULL; prev = NULL; ; Node *begin; Node *tail; Node *mark; List(const List &); List& operator=(const List&); ; Konstruktor Node() bude použit pro inicializaci uzlu tail Konstruktor Node(x, n) bude použit pro inicializaci uzlu vkládaného před uzel, na který ukazuje n (n bude vždy ukazatel mark, tj, ukazatel na kurzorem označený uzel)

p10\list\list.cpp Konstruktor a destruktor třídy List Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 20/27 List::List() { begin = tail = mark = new Node; prázdný seznam: begin tail mark List::~List() { Node *p; while (begin) { p = begin; begin = begin->next; delete p;

p10\list\list.cpp Testy na prázdnost a pozici kurzoru Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 21/27 bool List::empty() { return begin == tail; bool List::atBegin() { return mark==begin; bool List::atEnd() { return mark==tail;

p10\list\list.cpp Přesuny kurzoru Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 22/27 void List::toBegin() { mark = begin; void List::toEnd() { mark = tail; void List::toNext() { if (atend()) return; mark = mark->next; void List::toPrev() { if (atbegin()) return; mark = mark->prev;

p10\list\list.cpp Vložení prvku před kurzor void List::insert(T x) { Node *p = new Node(x, mark); mark->prev = p; if (atbegin()) begin = p; else p->prev->next = p; Poznámky: položku prev v novém prvku nastaví konstruktor (zkopíruje mark->prev) vkládá-li se před první prvek, je třeba p uložit do položky begin, jinak do položky next přechozího prvku Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 23/27

p10\list\list.cpp Odebrání prvku označeného kurzorem void List::remove() { if (atend()) return; Node *p = mark; mark->next->prev = mark->prev; if (atbegin()) begin = mark->next; else mark->prev->next = mark->next; mark = mark->next; delete p; Poznámky: je-li kurzor na konci, neodebere se nic ukazatel na další prvek (mark->next) se uloží do begin, pokus se odebírá první prvek, jinak do položky next předchozího prvku kurzor se posune na prvek za odebraným prvkem Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 24/27

p10\list\list.cpp Odebrání prvku před kurzorem void List::removePrev() { if (atbegin()) return; toprev(); remove(); Poznámky: je-li kurzor na začátku, neodebere se nic jinak se kurzor přesune na předchozí prvek a odebere se tento prvek metodou remove Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 25/27

p10\list\list.cpp Čtení hodnoty prvku a výpis seznamu Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 26/27 bool List::read(T &x) { if (atend()) return false; x = mark->val; return true; Poznámka: je-li kurzor na konci, do proměnné se nic neuloží ostream& operator<<(ostream& s, const List& lst) { s << '['; List::Node *p = lst.begin; while (p) { if (p==lst.mark) s << ' '; if (p!=lst.tail) s << p->val << ' '; p = p->next; s << ']'; return s;

Třída List Testovací program je v souboru p10\list\main.cpp Šablona třídy List je v souboru p10/list-sablona/list.h, testovací program pro šablonu je p10\list-sablona\main.cpp Vyzkoušejte! Karel Müller, Josef Vogel (ČVUT FIT) Abstraktní datové typy BI-PA2, 2011, Přednáška 10 27/27