Informatika I 7. přednáška RNDr. Jiří Dvořák, CSc.
Informatika I: přednáška 72 Obsah přednášky Rekurze Statické a dynamické proměnné Typ ukazatel Abstraktní dynamické datové struktury
Informatika I: přednáška 73 Rekurze Rekurze je proces řešení problému jeho rozdělením na dva nebo více jednodušších podproblémů, z nichž alespoň jeden je jednodušší verzí původního problému (jednodušší ve smyslu menšího rozsahu). Rekurze v programování je vždy spojena s rekurzivním voláním podprogramů (procedur nebo funkcí).
Informatika I: přednáška 74 Přímá a nepřímá rekurze Přímá rekurze: podprogram volá sám sebe. Nepřímá rekurze: podprogram P 1 volá podprogram P 2, podprogram P 2 volá podprogram P 3, …, podprogram P n-1 volá podprogram P n, podprogram P n volá podprogram P 1.
Informatika I: přednáška 75 Obvyklá struktura přímo rekurzivního podprogramu procedure Solve(problemP); begin if Podmínka then Řeš triviální případ daného problému else Solve(problemP’); {problém P’ je jednodušším případem problému P} end;
Informatika I: přednáška 76 Příklad rekurzivní funkce function Faktorial(N:byte):real; begin if N <= 1 then Faktorial:=1 else Faktorial:=N Faktorial(N-1); end;
Informatika I: přednáška 77 Problém hanojských věží Úkolem je přenést disky na druhou tyč s použitím třetí tyče jako pomocné, přičemž musí být dodržena tato pravidla: v každém kroku můžeme přenést pouze jeden disk, a to vždy z tyče na tyč není možné položit větší disk na menší
Informatika I: přednáška 78 Rekurzivní řešení problému hanojských věží procedure PrenesVez(N:byte; A,B,C:char); {Přenes věž o výšce N disků z tyče A na tyč B pomocí tyče C; disky jsou číslovány vzestupně od nejmenšího do největšího čísly 1, 2, …, N} begin if N=1 then Přenes disk N z tyče A na tyč B else begin PrenesVez(N-1,A,C,B); Přenes disk N z tyče A na tyč B; PrenesVez(N-1,C,B,A); end end;
Informatika I: přednáška 79 program Hanoj; {$APPTYPE CONSOLE} var N:byte; S:string; Plan:TextFile; procedure PrenesVez(N:byte; A,B,C:char); {prenese vez o vysce N z tyce A na tyc B pomoci tyce C} begin if N=1 then writeln(Plan,'Prenes disk',N:3,' z ',A,' na ',B) else begin PrenesVez(N-1,A,C,B); writeln(Plan,'Prenes disk',N:3,' z ',A,' na ',B); PrenesVez(N-1,C,B,A); end;
Informatika I: přednáška 710 begin writeln('Zadej jmeno souboru'); readln(S); assignfile(Plan,S); rewrite(Plan); writeln('Zadej pocet disku'); readln(N); PrenesVez(N,'A','B','C'); closefile(Plan); end.
Informatika I: přednáška 711 Prenes disk 1 z A na C Prenes disk 2 z A na B Prenes disk 1 z C na B Prenes disk 3 z A na C Prenes disk 1 z B na A Prenes disk 2 z B na C Prenes disk 1 z A na C Prenes disk 4 z A na B Prenes disk 1 z C na B Prenes disk 2 z C na A Prenes disk 1 z B na A Prenes disk 3 z C na B Prenes disk 1 z A na C Prenes disk 2 z A na B Prenes disk 1 z C na B Příklad řešení pro N = 4:
Informatika I: přednáška 712 Procedura QuickSort const MaxN=100; type TIndex=1..MaxN; TPole=array[TIndex] of integer; procedure QuickSort(L,R:TIndex; var A:TPole); {Procedura provadi vzestupne trideni prvku pole v useku vymezenem indexy L a R. Nejprve se stanovi hodnota stredoveho prvku X. Pak se prvky pole preskladaji tak, ze vzniknou dve prekryvajici se casti s temito vlastnostmi: v prve casti nejsou prvky vetsi nez X a ve druhe casti nejsou prvky mensi nez X. Pro intervaly indexu nepatrici do prekryti těchto casti se potom vola procedura QuickSort.} var I,J:TIndex; X,Pom:integer;
Informatika I: přednáška 713 begin I:=L; J:=R; X:=A[(L+R) div 2]; repeat while A[I]<X do I:=I+1; while A[J]>X do J:=J-1; if I<=J then begin Pom:=A[I]; A[I]:=A[J]; A[J]:=Pom; I:=I+1; J:=J-1; end; until I>J; if L<J then QuickSort(L,J,A); if I<R then QuickSort(I,R,A); end;
Informatika I: přednáška 714 Nepřímá rekurze a direktiva forward procedure Proc1(...); forward; procedure Proc2(...); begin... Proc1(...);... end; procedure Proc1; {Dokončení deklarace procedury Proc1} begin... Proc2(...);... end;
Informatika I: přednáška 715 Statické a dynamické proměnné Statické proměnné: Jsou deklarovány v úseku var (úsek deklarací proměnných) a existují po tu dobu, po kterou se výpočetní proces nachází v bloku, v němž jsou deklarovány. Dynamické proměnné: Jsou dynamicky vytvářeny v případě potřeby a rušeny v případě nepotřeby. Přístup k nim je zprostředkován pomocí proměnných typu ukazatel.
Informatika I: přednáška 716 Typ ukazatel a dynamická proměnná Definice: identif_typu_ukazatel = ^identif_typu_dynamické_proměnné; Přístup k dynamické proměnné: identif_proměnné_typu_ukazatel^ proměnná typu ukazatel dynamická proměnná Konstanta typu ukazatel: nil Jestliže proměnná typu ukazatel má tuto hodnotu, znamená to, že neukazuje na žádnou dynamickou proměnnou.
Informatika I: přednáška 717 Operace nad typem ukazatel Vytvoření dynamické proměnné: new(ProměnnáTypuUkazatel) Uvolnění paměti po dynamické proměnné: dispose(ProměnnáTypuUkazatel) Relační operace (pro stejné typy ukazatel): =, <> Operace přiřazení (pro stejné typy ukazatel): :=
Informatika I: přednáška 718 Příklady pro typ ukazatel Definice typů a deklarace proměnných: type TZaznam = record Re,Im:real; end; TPole = array[1..100] of integer; TUkZaznam = ^TZaznam; TUkPole = ^TPole; var P,Q:^string; UkA,UkB:TUkPole; UkZ:TUkZaznam; Vytvoření dynamických proměnných: new(P); new(Q); new(UkA); new(UkZ);
Informatika I: přednáška 719 Příklady pro typ ukazatel Naplnění dynamických proměnných : P^:='alfa'; Q^:=P^; readln(UkZ^.Re, UkZ^.Im); for i:=1 to N do readln(UkA^[i]); Rušení dynamické proměnné: dispose(P); Operace přiřazení pro typ ukazatel: P:=nil; UkB:=UkA;
Informatika I: přednáška 720 Abstraktní dynamické datové struktury Zásobník (stack) Fronta (queue) Seznam (list) Strom (tree) Graf (graph) Tyto struktury je možno implementovat pomocí typu pole nebo pomocí typu ukazatel.
Informatika I: přednáška 721 Zásobník Dynamická homogenní lineární struktura Přístupová metoda LIFO (Last In, First Out) Typické operace: vytvoření prázdného zásobníku vložení prvku do zásobníku zjištění hodnoty na vrcholu zrušení prvku na vrcholu test, zda je zásobník prázdný inout vrchol
Informatika I: přednáška 722 Fronta Dynamická homogenní lineární struktura Přístupová metoda FIFO (First In, First Out) Typické operace: vytvoření prázdné fronty vložení prvku na konec fronty zjištění hodnoty na čele fronty zrušení prvku na čele fronty test, zda je fronta prázdná outin
Informatika I: přednáška 723 Seznam Jednoduchý seznam: dynamická homogenní lineární struktura sekvenční přístupová metoda typické operace: –vytvoření prázdného seznamu –vložení prvku do seznamu –odebrání prvku ze seznamu –test, zda je seznam prázdný Obecný seznam: prvky mohou být opět seznamy
Informatika I: přednáška 724 Implementace jednoduchého seznamu Jednosměrný seznam Obousměrný seznam Cyklický seznam
Informatika I: přednáška 725 Příklad implementace seznamu studentů type TStudent=record OsCislo:integer; Prijmeni,Jmeno:TRetezec; Body:integer; end; TSpoj= ^TPrvek; TPrvek= record Stud:TStudent; Dalsi:TSpoj; end; var Zacatek,P,Q:TSpoj; Student:TStudent;
Informatika I: přednáška 726 Příklady práce se seznamem studentů Vytvoření prázdného seznamu: Zacatek:=nil; Vložení studenta na začátek seznamu: new(P); P^.Stud:=Student; P^.Dalsi:=Zacatek; Zacatek:=P; Zrušení studenta na začátku seznamu: P:=Zacatek; Zacatek:=Zacatek^.Dalsi; dispose(P);
Informatika I: přednáška 727 Příklady práce se seznamem studentů Nalezení studenta s daným osobním číslem: var OC:integer; {zadane osobni cislo} Nalez:TSpoj; {ukazatel na nalezeny zaznam}... P:=Zacatek; Nalez:=nil; while P<>nil do begin if P^.Stud.OsCislo=OC then begin Nalez:=P; P:=nil; end else P:=P^.Dalsi; end;
Informatika I: přednáška 728 Stromové struktury Binární strom (každý uzel má nejvýše dva následníky) Obecný strom (každý uzel může mít libovolný počet následníků)
Informatika I: přednáška 729 Implementace binárního stromu A D CB E A C B E D F F
Informatika I: přednáška 730 Příklad implementace obousměrného seznamu a binárního stromu type THodnota=... ; {typy pro obousmerny seznam} TSpoj= ^TPrvek; TPrvek= record Vzad:TSpoj; Hodnota:THodnota; Vpred:TSpoj; end; {typy pro binarni strom} THrana= ^TUzel; TUzel= record Hodnota:THodnota; Levy:THrana; Pravy:THrana; end;
Informatika I: přednáška 731 Implementace uzlu obecného stromu A A