Spojové struktury BI-PA1 Programování a algoritmizace 1, ZS

Slides:



Advertisements
Podobné prezentace
PLAYBOY Kalendar 2007.
Advertisements

Standardní knihovní funkce pro práci s textovými řetězci
Pro začátek něco lehčího
Orbis pictus 21. století Tato prezentace byla vytvořena v rámci projektu.
Programování v C jazyku - SEMINÁŘ
Vlastní skript může být umístěn: v hlavičce stránky v těle stránky
Dynamické dokumenty na straně klienta Informatika pro ekonomy II.
Programovací jazyk C++
Třída SIMSET je druhou standardní systémovou třídou, která obsahuje prostředky pro práci se spojovými seznamy. KRUHOVÉ SPOJOVÉ SEZNAMY Spojový seznam –
Přednáška 11 Jiří Šebesta
*Zdroj: Průzkum spotřebitelů Komise EU, ukazatel GfK. Ekonomická očekávání v Evropě Březen.
Racionální čísla, operátory, výrazy, knihovní funkce
Programování 2 Cvičení 5.
Spektra zatížení Milan Růžička 1 Dynamická pevnost a životnost
Cvičení Úloha 1: Rozhodněte zda posloupnost znaků v poli délky n tvoří palindrom (slovo, které je stejné při čtení zprava i zleva). Př.: [a,l,e,l,a] [a,n,n,a]
10. Dynamické datové struktury
Spojové struktury Spojová struktura ( linked structure ):
25/08/20141 Typ struktura (1) Datový typ struktura ( struct ) je agrego- vaný heterogenní datový typ Jedná se o skupinu několika proměnných, které mohou.
Red-Black Stromy Binární Vyhledávací Stromy, u kterých je časová složitost operací v nejhorším případě rovná O(log n)
1/12 ALGO – Algoritmizace 5. cvičení 1.ročník, ZS Ing. Zdena DOBEŠOVÁ, Ph.D.
PROGRAM PRO VÝUKU T ČLÁNKU
Cvičení 2 Proměnné(jednoduché a složené) a konstanty První program Zápis výrazů.
Programování v C++ Cvičení.
Algoritmizace a programování
Metody řazení s lineární časovou složitostí
Skip-List je datová struktura, která může být použita jako náhrada za vyvážené stromy. představují pravděpodobnostní alternativu k vyváženým stromům (struktura.
Vizualizace projektu větrného parku Stříbro porovnání variant 13 VTE a menšího parku.
Vzdělávací materiál / DUMVY_32_INOVACE_02B14 Příkazový řádek: obsah souborů PŘÍKLADY AutorIng. Petr Haman Období vytvořeníLeden 2013 Ročník / věková kategorie3.
Dělení se zbytkem 3 MODERNÍ A KONKURENCESCHOPNÁ ŠKOLA
MODERNÍ A KONKURENCESCHOPNÁ ŠKOLA reg. č.: CZ.1.07/1.4.00/ Základní škola, Šlapanice, okres Brno-venkov, příspěvková organizace Masarykovo nám.
Struktury, qsort, mergesort BI-PA1 Programování a algoritmizace 1, ZS Katedra teoretické informatiky © Miroslav Balík Fakulta informačních technologií.
Jazyk vývojových diagramů

A1PRG - Programování – Seminář Ing. Michal Standardní knihovní funkce pro práci se soubory 13 Verze
Posloupnosti, řady Posloupnost je každá funkce daná nějakým předpisem, jejímž definičním oborem je množina všech přirozených čísel n=1,2,3,… Zapisujeme.
Násobení zlomků – teorie a cvičení VY_32_INOVACE_19
OSNOVA: a) Řetězce v C b) Funkce stdio.h pro řetězce c) Funkce string.h pro řetězce d) Příklad Jiří Šebesta Ústav radioelektroniky, FEKT VUT v Brně Počítače.
Deklarace Radim Štefan. 2 Použité zkratky BP – Borland Pascal De – Delphi.
A1PRG - Programování – Seminář Ing. Michal Operátory (2. část) 4 Verze
C – strukturované příkazy
Jazyk vývojových diagramů
Časová složitost algoritmů, řazení a vyhledávání
A1PRG - Programování – Seminář Ing. Michal Ukazatele a pole 10 Verze
Další abstraktní datové typy
Cvičení.
3. Příkazy  Příkazy dělíme na jednoduché a strukturované.  Jednoduché příkazy - žádnou jejich dílčí částí neni příkaz - přiřazovací, vstupu a výstupu,
Příklady v jazyku C – část 4
Příklady v jazyku C – část 3
IB111 Programování a algoritmizace
STROMY Datová struktura sestávající z uzlů
7. Typ soubor Souborem dat běžně rozumíme uspořádanou množinu dat, uloženou mimo operační paměť počítače (na disku). Pascalský soubor je abstrakcí skutečného.
Napište program v C pro výpočet plochy obdélníka se stranami A=3 a B=2. Výsledek vytiskněte s patřičným komentářem na obrazovku formátovým příkazem printf.
Realloc a qsort examples BI-PA1 Programování a algoritmizace 1 Katedra teoretické informatiky © Miroslav Balík Fakulta informačních technologií České vysoké.
Rozklad problému na podproblémy, rekurze
Ukazatele BI-PA1 Programování a algoritmizace 1, ZS Katedra teoretické informatiky © Miroslav Balík Fakulta informačních technologií České vysoké.
Příklady v jazyku C – část 1. Výstupy pomocí printf. printf(" Tisk textu \n v apostrofech \n ") ; p=10; printf("%d\n", p) ; /* tisk konstanty */ printf("Tisk.
Vazby dynamických proměnných,databázové systémy Přednáška č. 10.
Soubory BI-PA1 Programování a algoritmizace 1, ZS Katedra teoretické informatiky © Miroslav Balík Fakulta informačních technologií České vysoké.
Jazyk C A0B36PRI - PROGRAMOVÁNÍ Část II.
C – if Mgr. Lenka Švancarová. if vývojový diagram Podmínka Příkaz(y) Podmínka Příkaz(y) Úplné větveníNeúplné větvení ++--
Pokročilé datové typy (struktury, unie, dynamické proměnné)
Programování KONSTANTY, ČTENÍ PO JEDNOM ZNAKU GETCHAR() FORMÁTOVANÝ VÝSTUP POMOCÍ PRINTF, VÝVOJOVÉ DIAGRAMY, CYKLY.
Programování ENUM, SWITCH,pole jednorozměrná a vícerozměrná, deklarace, inicializace, kopírování, porovnání Erik Král.
Programovací jazyk C++
Programování 2. hodina RNDr. Jan Lánský, Ph.D.
Abstraktní datové typy
Dynamické proměnné (1) Proměnné, jejichž počet a (nebo) velikost pa-měti využívané těmito proměnnými se v prů-běhu programu mění Dynamické proměnné lze.
Opakování ze 3. cvičení deklarace proměnných výpis na monitor (výstup)
Opakování ze 4. cvičení int a; printf("Zadej číslo: ");
Transkript prezentace:

Spojové struktury BI-PA1 Programování a algoritmizace 1, ZS 2012-2013 Příprava studijního programu Informatika je podporována projektem financovaným z Evropského sociálního fondu a rozpočtu hlavního města Prahy. Praha & EU: Investujeme do vaší budoucnosti Spojové struktury BI-PA1 Programování a algoritmizace 1, ZS 2012-2013 Katedra teoretické informatiky © Miroslav Balík Fakulta informačních technologií České vysoké učení technické

Obsah Téma shrnutí typu struktura spojové seznamy stromy vložení nového prvku na začátek spojového seznamu průchod spojovým seznamem vložení nového prvku na konec spojového seznamu stromy příklad binárního stromu Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Shrnutí typu struktura Syntaxe popisu struktury: struct značka { seznam popisů položek } Popisy položek mají podobný tvar, jako deklarace proměnných položka nesmí být typu stejná struktura položka může být ukazatelem na stejnou strukturu struct osoba { char jmeno[20]; char prijmeni[25]; int rok_narozeni; }; /* deklarace struktury */ struct osoba Jan; /* deklarace proměnné typu struct osoba */ Značka struktury není identifikátorem typu osoba Petr; /* chyba */ Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Shrnutí typu struktura Identifikátor typu lze pro strukturu zavést deklarací typu typedef struct Complex {float Real, Imag;} Complex; Complex a, b; /* O.K. */ Zpřístupnění položky struktury: Přímá selekce: X . položka kde X je výraz typu struct Nepřímá selekce (přes ukazatel): X -> položka kde X je výraz typu ukazatel na struct X -> položka je zkratkou za (*X) . položka struct { int a; char b; } x, *px = &x; x.a = 1; px -> b = ‘a’; (*px).b = ‘a’; /* totéž */ Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Úvodní příklad na spojové seznamy Program, který přečte řadu celých čísel zakončených nulou a vypíše je v opačném pořadí (bez závěrečné nuly) Úlohu jsme řešili: pomocí rekurzivní procedury (nebylo třeba omezit počet čísel) pomocí pole (bylo třeba omezit počet čísel) Vyřešme ji pomocí dynamických proměnných, z nichž vytvoříme spojový seznam (nebude potřeba omezit počet čísel). Princip: pro každé přečtené číslo dynamicky vytvoříme proměnnou typu struktura, v jejíž jedné položce bude číslo a ve druhé ukazatel na další proměnnou obsahující dříve přečtené číslo Příklad: pro vstupní posloupnost 5 10 0 vytvoříme: dynamicky vytvořené proměnné 10 5 15 Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Úvodní příklad na spojové seznamy Dynamicky vytvářené proměnné budou typu Prvek: typedef struct prvek { int hodn; struct prvek *dalsi; } Prvek; Pro vytvoření dynamické proměnné typu Prvek zavedeme funkci: Prvek *vytvorPrvek(int hodn, Prvek *dalsi) { Prvek *pom = (Prvek*)malloc(sizeof(Prvek)); pom->hodn = hodn; pom->dalsi = dalsi; return pom; } Ukazatelem na první prvek spojového seznamu bude proměnná Prvek *zacatek = NULL; lépe sizeof(*pom), velikost vypočítá překladač (od C99 až za běhu) podle proměnné, odolnější proti chybě programátora Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Úvodní příklad na spojové seznamy Postup při vytvoření spojového seznamu: pokud přečtené číslo není nula, pak uložíme ho do dynamicky vytvořené proměnné typu Prvek, která v položce další bude obsahovat ukazatel na začátek doposud vytvořeného spojového seznamu ukazatel na novou proměnnou typu Prvek se stane ukazatelem na rozšířený spojový seznam skončíme, když je přečtené číslo nula pak spojový seznam projdeme od začátku do konce a čísla vypíšeme Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Úvodní příklad - prog12-seznam1.c int main(void) { Prvek *zacatek = NULL, *p; int cislo; printf("zadej posloupnost cisel zakoncenou nulou\n"); scanf("%d", &cislo); while (cislo) { zacatek = vytvorPrvek(cislo, zacatek); } printf("vypis cisel v opacnem poradi\n"); p = zacatek; while (p) { printf("%d ", p->hodn); p = p->dalsi; printf("\n"); system("PAUSE"); return 0; Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Druhý příklad Úvodní příklad ilustroval: vytváření spojového seznamu vkládáním prvku na začátek průchod spojovým seznamem a provedení operace pro všechny prvky Další příklad na průchod spojovým seznamem (prog12-seznam2.c): přečteme čísla zakončená nulou vytvoříme z nich spojový seznam (vkládáním prvku na začátek seznamu) pak čteme další posloupnost čísel zakončenou nulou pro každé číslo vypíšeme, zda je či není prvkem spojového seznamu Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Druhý příklad Funkce pro výpis seznamu void vypisSeznamu(Prvek *p) { while (p) { printf("%d ", p->hodn); p = p->dalsi; } printf("\n"); Funkce pro hledání hodnoty v seznamu int jePrvkem(Prvek *p, int x) { while (p && p->hodn!=x) p = p->dalsi; if (p) return 1; else return 0; Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Druhý příklad – funkce main int main(void) { Prvek *zacatek = NULL, *p; int cislo; printf("zadej posloupnost cisel zakoncenou nulou\n"); scanf("%d", &cislo); while (cislo) { zacatek = vytvorPrvek(cislo, zacatek); } printf("vypis cisel v opacnem poradi\n"); vypisSeznamu(zacatek); printf("zadej dalsi posloupnost cisel zakoncenou nulou\n"); ... Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Druhý příklad – funkce main, 2. část ... printf("zadej dalsi posloupnost cisel zakoncenou nulou\n"); scanf("%d", &cislo); while (cislo) { printf("cislo %d ", cislo); if (jePrvkem(zacatek, cislo)) printf("je "); else printf("neni "); printf("prvkem seznamu\n"); } printf("\n"); system("PAUSE"); return 0; Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Vložení prvku na konec spojového seznamu I přečteme posloupnost čísel zakončenou nulou vytvoříme spojový seznam, ve kterém budou čísla v pořadí, v jakém jsou čtena seznam vypíšeme Seznam budeme vytvářet vkládáním nového prvku na konec K vložení na konec musíme najít poslední prvek seznamu poslední prvek má v položce dalsi hodnotu NULL na počátku je seznam prázdný, tj. zacatek je NULL Zavedeme funkci: Prvek *najdiPosledni(Prvek *p) { if (!p) return NULL; while (p->dalsi) p = p->dalsi; return p; } Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Vložení prvku na konec spojového seznamu I /*prog12-seznam3a.c*/ int main(void) { Prvek *zacatek = NULL, *posledni, *p; int cislo; printf("zadej posloupnost cisel zakoncenou nulou\n"); scanf("%d", &cislo); while (cislo) { p = vytvorPrvek(cislo, NULL); posledni = najdiPosledni(zacatek); if (posledni) posledni->dalsi = p; else zacatek = p; } printf("vypis cisel\n"); vypisSeznamu(zacatek); system("PAUSE"); return 0; Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Vložení prvku na konec spojového seznamu II Pokud při vkládání prvku na konec spojového seznamu hledáme poslední prvek, má operace vložení lineární časovou složitost O(n) Poznámka: operace vložení prvku na začátek spojového seznamu má konstantní časovou složitost O(1) int main(void) { Prvek *zacatek = NULL, *posledni = NULL, *p; int cislo; scanf("%d", &cislo); while (cislo) { p = vytvorPrvek(cislo, NULL); if (posledni) posledni->dalsi = p; else zacatek = p; posledni = p; } ... } Vložení prvku na konec spojového seznamu bude mít konstantní složitost, budeme-li si pamatovat ukazatel na poslední prvek (prog12-seznam3b.c) Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Spojové struktury Spojový seznam z předchozích příkladů patří mezi spojové struktury Spojová struktura (linked structure): množina objektů propojených pomocí spojů (ukazatelů) Spoj často vyjadřuje vztah předchůdce – následník Lineární spojové struktury (spojové seznamy): každý prvek struktury má nanejvýš jednoho následníka Příklady spojových seznamů: jednosměrný dvousměrný cyklický jednosměrný Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Stromy Nelineární spojová struktura: každý prvek může mít více následníků Příkladem nelineární spojové struktury je strom (prvky nazýváme uzly) Binární strom: každý uzel má nanejvýš dva následníky kořen stromu levý podstrom pravý podstrom list Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Realizace binárního stromu Struktura uzlů: Příklad binárního stromu: Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Příklad – dekódování morseovky Pro dekódování textu zapsaného v Morseově abecedě lze použít následující binární strom . - H V F L P J B X C Y Z Q S U R W D K Z O I A N M E T . - . - Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Příklad – dekódování morseovky Strom vytvoříme ze struktur typu MUzel typedef struct MUzel { char znak; struct MUzel *tecka, *carka; } MUzel; …… a pomocí funkcí: MUzel *novyMUzel(char z, MUzel *t, MUzel *c) { MUzel *p = (MUzel*)malloc(sizeof(MUzel)); p->znak = z; p->tecka = t; p->carka = c; return p; } MUzel *novyMUzel1(char z) { p->znak = z; p->tecka = NULL; p->carka = NULL; Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Dekódování morseovky, vytvoření stromu MUzel *strom() { return novyMUzel(' ', novyMUzel('E', /* . */ novyMUzel('I', /* .. */ novyMUzel('S', /* ... */ novyMUzel1('H'), /* .... */ novyMUzel1('V') /* ...- */ ), novyMUzel('U', /* ..- */ novyMUzel1('F'), /* ..-. */ NULL ) /* ..-- */ novyMUzel('A', /* .- */ ... ) novyMUzel('T', /* - */ ...) ); } Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Příklad – dekódování morseovky Prvním parametrem je řetěz obsahující Morseův kód a druhým parametrem je pole, kam se uloží dekódovaný text void dekoduj(char odkud[], char kam[]) { MUzel *aktualni = koren; int i = 0, j = 0, delka = strlen(odkud); while (i<delka) { char z = odkud[i]; if (aktualni!=NULL) { if (z=='.') aktualni = aktualni->tecka; else if (z=='-') aktualni = aktualni->carka; else { kam[j++] = aktualni->znak; aktualni = koren; } i++; } else { kam[j++] = '?'; while (odkud[i]=='.' || odkud[i]=='-') i++; aktualni = koren; } kam[j] = 0; Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Dekódování morseovky - main /* prog12-morseovka.c*/ MUzel *koren; #define MAXDELKA 100 int main() { koren = strom(); char morse[MAXDELKA], text[MAXDELKA]; fgets(morse, MAXDELKA, stdin); dekoduj(morse, text); fprintf(stdout, "%s\n", text); system("PAUSE"); return 0; } Ing. Miroslav Balík, Ph.D. - BI-PA1- 12

Příklad - hra „Jaké zvíře si myslíš“ Příklad dialogu počítače a člověka : Myslite si nejake zvire? ano leta? ne Je to ryba? Neuhadl jsem. Prosim o doplneni znalosti. Jake zvire jste myslel? pes Napiste otazku vystihujici rozdil mezi pes a ryba steka Pro pes je odpoved ano ci ne Dekuji, chcete pokracovat?... Ing. Miroslav Balík, Ph.D. - BI-PA1- 12 pro zájemce

Příklad - hra „Jaké zvíře si myslíš“ Počáteční strom : Strom po doplnění znalostí: Ing. Miroslav Balík, Ph.D. - BI-PA1- 12 pro zájemce

„Jaké zvíře si myslíš“ -hrubé řešení "úvod dialogu"; "aktuálním uzlem je kořen stromu"; do { "polož otázku uvedenou v aktuálním uzlu"; if ("odpověď je ano") "aktuálním uzlem je levý následník“; else "aktuálním uzlem je pravý následník“; } while ("aktuální uzel není list"); "polož závěrečnou otázku, název zvířete vyber z aktuálního uzlu"; if ("odpověď je ano") "hádání bylo úspěšné“; else { "hádání bylo neúspěšné"; "doplň znalosti" } Ing. Miroslav Balík, Ph.D. - BI-PA1- 12 pro zájemce

„Jaké zvíře si myslíš“ – uzel a vytvoření typedef struct Uzel { char text[MAXDELKA]; struct Uzel *ano, *ne; } Uzel; Uzel *vytvorUzel1(char t[]) { Uzel *u = (Uzel*)malloc(sizeof(Uzel)); strcpy(u->text, t); u->ano = NULL; u->ne = NULL; return u; } Uzel *vytvorUzel(char t[], Uzel *a, Uzel *n) { u->ano = a; u->ne = n; Ing. Miroslav Balík, Ph.D. - BI-PA1- 12 pro zájemce

„Jaké zvíře si myslíš“ Test, zda uzel je listem, inicializaci stromu a čtení odpovědi: int jeList(Uzel *u) { return u->ano==NULL && u->ne==NULL; } Uzel *inicializaceStromu() { return vytvorUzel("leta?", vytvorUzel1("ptak"), vytvorUzel1("ryba") ); } int odpovedAno() { char odpoved[MAXDELKA]; scanf("%s", odpoved); if (odpoved[0]=='a' || odpoved[0]=='A') return 1; else return 0; Ing. Miroslav Balík, Ph.D. - BI-PA1- 12 pro zájemce

„Jaké zvíře si myslíš“ – main /* prog12-hra.c */ int main() { Uzel *koren = inicializaceStromu(); Uzel *aktualni = koren; for (;;) { printf("Myslite si nejake zvire?\n"); if (!odpovedAno()) break; do { printf("%s\n", aktualni->text); if (odpovedAno()) aktualni = aktualni->ano; else aktualni = aktualni->ne; } while (!jeList(aktualni)); printf("Je to %s?\n", aktualni->text); if (odpovedAno()) printf("Uhadl jsem\n"); else { printf("Neuhadl jsem. Prosim o doplneni znalosti\n"); doplnPodstrom(aktualni); } printf("Dekuji. Chcete pokracovat?\n"); } return 0; } Ing. Miroslav Balík, Ph.D. - BI-PA1- 12 pro zájemce

„Jaké zvíře si myslíš“- doplnění znalostí: void doplnPodstrom(Uzel *p) { char noveZvire[MAXDELKA], novaOtazka[MAXDELKA]; Uzel *novyAno, *novyNe; printf("Jake zvire jste myslel?\n"); scanf("%s", noveZvire); printf("Napiste otazku vystihujici rozdil mezi %s a %s\n", noveZvire, p->text); scanf("%s", novaOtazka); printf("Pro %s je odpoved ano ci ne?\n", noveZvire); if (odpovedAno()) { novyAno = vytvorUzel1(noveZvire); novyNe = vytvorUzel1(p->text); } else { novyAno = vytvorUzel1(p->text); novyNe = vytvorUzel1(noveZvire); } strcpy(p->text, novaOtazka); p->ano = novyAno; p->ne = novyNe; Ing. Miroslav Balík, Ph.D. - BI-PA1- 12 pro zájemce