10 . Dynamické datové struktury
date post
21-Mar-2016Category
Documents
view
45download
2
Embed Size (px)
description
Transcript of 10 . Dynamické datové struktury
10. Dynamick datov struktury Statick datov struktura - jej rozsah se bhem provdn programu nemn - pole, zznamy.
Dynamick datov struktura - jej rozsah se bhem vpotu mn. Vytv se pomoc dynamickch promnnch, jejich spojovnm do seznam.
Dynamick promnn je typu zznam a obsahuje jeden jeden nebo vce ukazatelu na tento typ zznam.
Nejjednodu dynamickou datovou strukturou je linern seznam, ve kterm kad dynamick promnn ukazuje na svho nslednka a jedna promnn typu ukazatel ukazuje na jeho zatek.
Operace nad spojovm seznamem:
- pidn prvku na zatek seznamu: prvek^.dalsi:=zacatek;zacatek:=prvek;
- odebrn prvnho prvku v seznamu: zacatek:=zacatek^.dalsi;
- proveden operace pro vechny prvky v seznamu:
p:=zacatek; s:=0;while p nil do begin s:=s + p^.hodnota; {proveden operace s p^} p:=p^.dalsi;end;
- pidn prvku na konec seznamu:
posledni^.dalsi:=prvek;posledni:=prvek;
- vloen prvku za oznaen prvek
prvek^.dalsi:=za^.dalsi;za^.dalsi:=prvek;
- vloen prvku ped oznaen prvek
Procedura vyhled prvek pedchzejc prvek ped kter chceme vloit a provede vloen za tento prvek.
procedure vlozpred(var zacatek:spoj; prvek,pred:spoj);var p:spoj;begin if pred=zacatek then begin prvek^.dalsi:=zacatek; zacatek:=prvek end else begin p:=zacatek; while p^.dalsipred do p:=p^.dalsi; prvek^.dalsi:=pred; p^.dalsi:=prvek; end;end;
Je-li seznam rozshl, vkldme nov prvek tak, e vymnme hodnoty novho a oznaenho prvku a nov prvek pak vlome za oznaen:
procedure vlozpred(pred,prvek:spoj);var pom:integer;begin pom:=pred.hodnota; pred^.hodnota:=prvek^.hodnota; prvek^.hodnota:=pom; prvek^.dalsi:=pred^.dalsi; pred^.dalsi:=prvek;end;
- odebrn oznaenho prvku:
1. Najdeme prvek, kter v seznamu pedchz oznaen prvek procedure odeber(var zacatek:spoj; co:spoj);var p:spoj;begin if co=zacatek then zacatek:=zacatek^.dalsi else begin p:=zacatek; while p^.dalsico do p:=p^.dalsi; p^.dalsi:=co^.dalsi; end;end;
2. Do oznaenho prvku pesuneme hodnotu nsledujcho prvku a tento nsledujc prvek odebereme (nelze pro posledn prvek).
procedure odeber(co:spoj);begin if co^.dalsinil then begin co^.hodnota:=co^.dalsi^.hodnota; co^.dalsi:=co^.dalsi^.dalsi; end;end;
Linern seznam me bt spojen ukazateli obousmrn - krom ukazatele na dal prvek obsahuje promnn typu objekt tak ukazatel na pedchoz prvek.
type spoj=^objekt objekt=record / /zacatek konec hodnota:integer; dalsi,predchozi:spoj; end;
Takov datov struktura je vhodn napklad pro tvorbu textovho editoru.
Specilnm ppadem jednosmrn vzanho linernho seznamu je zsobnk nebo fronta.
Zsobnk
Zsobnkem rozumme takovou dynamickou datovou strukturu, z n se prvky vybraj v opanm poad ne v jakm se do n vkldaj. Vybrme tedy vdy posledn vloen prvek (podle toho se zsobnky tak nazvaj struktury LIFO - z anglickho Last-In-First-Out).
Pkladem pouit zsobnku je historie v internetovch prohlech. Kdy kliknete na zpt, oteve se posledn oteven strnka.Pro zsobnk meme definovat tyto zkladn operace:
vytvoen przdnho zsobnku vloen prvku na vrchol zsobnku odebrn prvku z vrcholu zsobnku testovn przdnosti zsobnku
Zsobnk meme v Pascalu implementovat (vytvoit) bu pomoc pole, tedy jako statickou datovou strukturu, nebo pomoc ukazatele, tedy jako dynamickou datovou strukturu.
Implementace pomoc pole:
Pi tto implementaci jsme nuceni omezit maximln velikost zsobnku a pekroen tto velikosti musme v programu oetit. Tak musme oetit opan stav, kdy chceme ze zsobnku prvek odebrat, ale zsobnk je ji przdn.
const Maxdelka = N; {N je slo omezujc maximln dlka zsobnku} var zasobnik : array[1..Maxdelka] of datovytyp; vrchol : 1..Maxdelka; procedure Vytvor; begin vrchol := 0; end;
function Jeprazdny: boolean; begin if vrchol = 0 then Jeprazdny := true; else Jeprazdny := false; end;
procedure Vloz(X: datovytyp); begin if vrchol = Maxdelka then begin {oeten pekroen maximln velikosti} write('Pozor - zasobnik je plny.'); Halt; end; else begin vrchol := vrchol + 1; zasobnik[vrchol] := X; end; end; procedure Odeber(var X: datovytyp); begin if vrchol = 0 then begin {oeten przdnosti zsobnku} write('Pozor - zasobnik je prazdny.'); Halt; end; else begin X := zasobnik[vrchol]; vrchol := vrchol - 1; end; end;
Implementace pomoc ukazatele:
Pokud budeme chtt implementovat zsobnk pomoc ukazatele, nemusme eit maximln velikost zsobnku. Ta je dna velikost t sti operan pamti, ve kter se vytvej dynamick promnn - hromada (heap). Prvky se vkldaj a odebraj na zatku jednosmrn vzanho linernho spojovho seznamu.
type spoj = ^objekt objekt = record hodnota: datovytyp; dalsi: spoj; end; var zasobnik : spoj; procedure Vytvor; begin zasobnik := nil; end;
function Jeprazdny: boolean; begin if zasobnik = nil then Jeprazdny := true; else Jeprazdny := false; end;
procedure Vloz(X: datovytyp); var pom: spoj; begin new(pom); with pom^ do begin hodnota := X; dalsi := zasobnik; end; zasobnik := pom; end; procedure Odeber(var X: datovytyp); var pom: spoj; begin if zasobnik = nil then begin write('Pozor - zasobnik je prazdny.'); Halt; end; else begin X := zasobnik^.hodnota; pom := zasobnik; zasobnik := zasobnik^.dalsi; dispose(pom); end; end;
Fronta
Fronta je dynamick datov struktura podobn zsobnku, rozdl je pouze v tom, e prvky se z fronty odebraj v tom poad, v jakm se do fronty vkldaj. Jako pklad si meme pedstavit frontu nakupujcch v obchod. Podle toho se datov typ fronta tak nazv struktura FIFO - z anglickho First-In-First-Out. Pro frontu meme definovat tyto operace:
vytvoen przdn fronty vloen prvku na konec fronty odebrn prvku ze zatku fronty test przdnosti fronty
Frontu stejn jako zsobnk meme implementovat bu pomoc pole, nebo pomoc ukazatele.
Implementace pomoc pole:
Pi tto implementaci musme neustle vdt, kde fronta zan, kde kon a kolik m prvk. Tak co se te velikosti, musme omezit maximln velikost fronty a pekroen tto velikosti musme oetit. Pokud budeme vkldat prvky do przdn fronty, bude situace vypadat nsledovn:
Vidme, e do fronty byly postupn vloeny hodnoty a a f.
. Pokud budeme s frontou pracovat tak, e star prvky z n budeme podle poteby vybrat, nov do n budeme vkldat, zjistme, e pro nov vloen nm nemus zbt polko ve front, zatmco po odebranch prvcch ze zatku fronty nm zbvaj voln a nevyuit polka. Situace me vypadat nap. takto:
Takovto problm meme vyeit nap. tm, e po kadm vbru prvku ze zatku fronty meme celou frontu pesypat na zatek, neboli vechny prvky budeme pesunovat o jedno msto dopedu.
Jednodum eenm, kter meme pirovnat k pedchozmu een, je pouit tzv. kruhov fronty. Za nslednka poslednho prvku povaujeme u takovto kruhov fronty prvn prvek.
Jak je vidt z obrzku, prvnm prvkem je zde prvek s indexem 0 a posledn prvek m index N-1 vzhledem k tomu, e pidvn a odebrn prvk do a z fronty, resp. vpoet indexu prvku, je realizovno pomoc operace modulo N.
V nsledujcm vpisu jsou procedury vytvoen przdn fronty, pidn prvku do fronty, odebrn prvku z fronty a funkce testovn przdnosti fronty.
const MaxDelka = N; {N je slo omezujc dlku fronty} MaxIndex = N-1; var fronta: array[1..MaxDelka] of datovytyp; zacatek, konec: MaxIndex; delka: MaxDelka; procedure Vytvor; begin zacatek := 0; konec := 0; delka := 0; end;
function JePrazdna: boolean; begin if delka = 0 then JePrazdna := true else JePrazdna := false; end;
procedure Vloz(X: datovytyp); begin if delka = MaxDelka then begin {oeten pekroen maximln velikosti} write('Pozor - fronta je plna.'); Halt; end; else begin fronta[konec] := X; konec := (konec + 1) mod MaxDelka; delka := delka + 1; end; end; procedure Odeber(var X: datovytyp); begin if delka = 0 then begin {oeten przdnosti fronty} write('Pozor - fronta je prazdna.'); Halt; end; else begin X := fronta[zacatek]; zacatek := (zacatek + 1) mod MaxDelka; delka := delka - 1; end; end;
Implementace pomoc ukazatele:
Podobn jako u zsobnku, kontrola maximln velikosti fronty odpad a maximln velikost fronty je dna velikost hromady, ve kter je fronta dynamicky vytvoena. V procedue Odeber je pouita pomocn promnn pom typu spoj, kterou vyuijeme k odstrann prvnho prvku fronty.
type spoj = ^objekt; objekt = record hodnota: datovytyp; dalsi: spoj; end; var zacatek, konec: spoj; procedure Vytvor; begin new(zacatek); konec := zacatek; end;
procedure Vloz(X: datovytyp); begin konec^.hodnota := X; new(konec^.dalsi); konec := konec^.dalsi; end; procedure Odeber(var X: datovytyp); var pom: spoj; begin if zacatek = konec then begin write('Pozor - fronta je prazdna.'); Halt; end else begin X := zacatek^.hodnota; pom := zacatek; zacatek := zacatek^.dalsi; dispose(pom); end; end; function JePrazdna: boolean; begin if zacatek = konec then JePrazdna := true else JePrazdna := false; end;
Binrn strom
Sloitj dynamickou datovou strukturou je binrn strom, ve kterm z kadho uzlu vychzej nejve dv hrany.
Vytv se pomoc typu uzel:
type spoj=^uzel; uzel=record ho