310 likes | 459 Vues
Informatika I 7 . přednáška. RNDr. Jiří Dvořák, CSc. dvorak @uai.fme.vutbr.cz. Obsah přednášky. Rekurze Statické a dynamické proměnné Typ ukazatel Abstraktní dynamické datové struktury. Rekurze.
E N D
Informatika I7. přednáška RNDr. Jiří Dvořák, CSc. dvorak@uai.fme.vutbr.cz
Obsah přednášky • Rekurze • Statické a dynamické proměnné • Typ ukazatel • Abstraktní dynamické datové struktury Informatika I: přednáška 7
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 7
Přímá a nepřímá rekurze • Přímá rekurze: podprogram volá sám sebe. • Nepřímá rekurze: podprogram P1 volá podprogram P2, podprogram P2 volá podprogram P3, … , podprogram Pn-1 volá podprogram Pn, podprogram Pn volá podprogram P1. Informatika I: přednáška 7
Obvyklá struktura přímo rekurzivního podprogramu procedure Solve(problemP); begin if Podmínkathen Ř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 7
Příklad rekurzivní funkce function Faktorial(N:byte):real; begin if N <= 1 then Faktorial:=1 else Faktorial:=NFaktorial(N-1); end; Informatika I: přednáška 7
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 7
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 7
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; end; Informatika I: přednáška 7
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 7
Příklad řešení pro N = 4: 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 Informatika I: přednáška 7
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 7
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 7
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 7
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 7
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 7
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 7
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 7
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 7
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 7
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ý out in vrchol Informatika I: přednáška 7
Fronta out in • 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á Informatika I: přednáška 7
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 7
Implementace jednoduchého seznamu Jednosměrný seznam Obousměrný seznam Cyklický seznam Informatika I: přednáška 7
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 7
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 7
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; whileP<>nil do begin if P^.Stud.OsCislo=OC thenbegin Nalez:=P; P:=nil; end else P:=P^.Dalsi; end; Informatika I: přednáška 7
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 7
Implementace binárního stromu A A B B C C D E D E F F Informatika I: přednáška 7
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 7
Implementace uzlu obecného stromu A A Informatika I: přednáška 7