420 likes | 665 Views
Rekordok Dinamikus tárkezelés és p ointer ek Dinamikusan láncolt listák. Ismétlés : Re k ord ok. Ez az azonosító mostantól egy típus, amit bárhol felhasználhatunk, mint pl. a “ word ” típust. Minek nevezzük ezeket ?. Re kordok rekordokon belül. Semmi nem akadályoz meg minket abban,
E N D
RekordokDinamikus tárkezeléséspointerekDinamikusan láncolt listák
Ez az azonosítómostantól egy típus, amit bárhol felhasználhatunk,mint pl. a “word” típust. Minek nevezzük ezeket? Rekordokrekordokon belül Semmi nem akadályoz meg minket abban, hogy rekordokat használjunk egy rekord mezőjeként : Type datum_tipus = record nap, honap, ev:word; end; diak_tipus = record nev: string[20]; osztaly: byte; szul_nap:datum_tipus; erettsegi_nap:datum_tipus; end; Típusok
naphonapev nev osztaly naphonapev naphonapev Rekordok rekordokon belül datum_tipus: diak_tipus: Var bob:diak_tipus; bob.szul_nap.honap := 6; szul_nap erettsegi_nap
Típusok vagyváltozók • Típusdefiníciók (TYPE) • Új típusokathozunk létre, ha összetett adatszerkezeteket használunk, vagy teljesen új fajta adattípussal kell dolgoznunk • Nem hoz létre változót – nincs tárhelyfoglalás • A felhasználási körekorlátlan • Változók deklarálása (VAR) • Aktuálisan foglal helyet a memóriában az adatnak • Korlátozott a felhasználása – csak az őt tartalmazó modul “látja” a változót (alprogram, főprogram) • Egy márlétezőadattípussal használható
Dinamikuskontra statikus Statikus (rögzített méretű) • Néha olyan adatszerkezeteket használunk, melyek “rögzítettek”és nincs szükségünk méretük növelésére vagy csökkentésére. Dinamikus (méretében változó) • Máskor, szeretnénknövelni vagy csökkenteniaz adatszerkezeteink méretét, hogy megfeleljenek a feladat követelményeinek.
Statikusadatok a program futása előttdeklarálódnak. Egy adott modulban deklarálódnak (vagy a főprog-ramban) és addig “maradnak életben” amíg az illető modul aktív. Ha több statikus adatot deklarálunk, mint amire szükségünk van feleslegesen foglalunk tárhelyet . Ha kevesebb statikus változót deklarálunk a szüksé-gesnél, nem tudjuk majd megoldani a feladatot. A valós életbeli problémák megoldása során gyakran fordul elő, hogy nem tudjuk hány változót kell előre deklarálnunk, ezek száma időben változni fog. Statikus adatok
Dinamikusadatok • Dinamikus adatokidőben nőnek vagy csökkennek, méretük szerint, a követelményeknek megfelelően. • Bármikor szükséges létrehozhatunk dinamikus változókatés tárhelyet allokálhatunk (foglalhatunk) számukra. • Bármikor szükséges felszabadíthatjuk(kill) a dinamikus változók által lefoglalt tárhelyet. • A legfontosabb előnye a dinamikus adatoknak, hogy mindig pontosanannyi változóval dolgozunk, amennyire szükség van, sem többel, sem kevesebbel. • Például, pointerekkel (mutatókkal)összekapcsolhatunk adatokat és dinamikus adatszerkezeteket hozhatunk létre, mint a láncolt listák vagy dinamikusan ábrázolt bináris fák.
Megjegyzés • A dinamikus adatok használata sokkal nagyobb rugalmasságot biztosít. • A memória még mindig véges !! • Mostantól viszont mi használjuk fel, ahogyan akarjuka memóriát. • És tesszük ezt a program futása közben. Példák: Nyomtató várakozási sora Repülésirányító ....akármi más ?, adj példát
Heap (Kupac)(DinamikusRész) (lefelé foglal új helyet) Verem (StatikusRész) (felfelé foglal új helyet) Kódszegmens (a program forráskódjáttartalmazó modul) A memória szerkezete egy program esetén
Ez milyen típusú változó??? 12 Heap A Heap (kupacmemória) Főprogramegy_változómás_változó ptr 4 7 Aheapa memóriának egy része, ahol a dinamikus tárkezelés megvalósul A statikusváltozók az adatszegmensben vagy a veremszegmensben kapnak helyet (ezek is a memóriának részei)
A NEW() eljárás • paramétere egy mutató • tárhelyet foglal le a heap-ben, egy adott típusú mutatónak megfelelő méretet Var p: ^byte; ps:^string; new(p); new(ps);
Dinamikusan tárolt adat elérése pointerrel 43 Heap: dinamikus • Mikor “követünk egy mutatót”, azt mondjukelvonatkoztatunkaz illető pointertől • A kalap (^) jelentése “a pointernél levő adat” • p^jelentése”kövesd, hogy a pmire mutat” • p^:=43;érvényes értékadás Főprogram p Adatsz.: Statikus
Képernyőn: Var P,Q:^word; new(P); P^:= 5; Q:= P; writeln(P^, Q^); Q^ := 7; writeln(P^, Q^); Pointer Animation of Numbers 5 5 5 5 7 7 word típus Pointer P 5 7 Pointer Q statikus dinamikus
nev CNP Egy record,amelykétadatot fog tárolni - egy nevetés egy személyi számot (CNP) : Type diak = record nev : String[20]; CNP :longint; end; Egymutató(pointer)egy diak rekordhoz: Var pdiak : ^diak; New(pdiak);
Pointerekésrekordok Bob pdiak 123456789 statikus dinamikus pdiak
Pointerekésrekordok Bob pdiak 123456789 statikus dinamikus pdiak^
Pointerekésrekordok Bob pdiak 123456789 statikus dinamikus pdiak^.nev := ’Bob’;
Pointerekésrekordok Bob pdiak 123456789 statikus dinamikus pdiak^.CNP := 123456789;
Listák tulajdonságai • Sokszor azonos típusú adatokkal kell dolgoznunk • Néha csak kevés memóriára lenne szükségünk: • Néha viszont sok memóriát kell használnunk: • Ilyen esetekben a megszokott módon nem deklarálhatunk változókat, mertnem tudjuk előre hány változót kell deklarálnunk • Más módon kell megoldanunk az adatok dinamikus (futás közbeni) helyfoglalását (allokációját) illetve a lefoglalt tárhely felszabadítását.
Láncoltlisták Mutatók (pointerek) segítségével azadatokat össze tudjuk fűzni („láncolni”): Type lista = ^lista_elem; lista_elem = Record adat: word; kov: lista; End; 4 17 42 NIL
Láncolt lista egy elemének létrehozása Type lista = ^lista_elem; {mutató a lista egy eleméhez} lista_elem = Record adat: word; {itt a feladattól függően,} kov: lista; {szerepelhet több mező is} End; {a lista egy eleme} Var akt_elem: lista; new(akt_elem); {lefoglal helyet egy listaelemnek}
akt_elem ^.adat akt_elem ^.kov Mutatók és láncolt listák akt_elem statikus dinamikus akt_elem^
Egy listaelem mezőinek elérése 42 akt_elem NIL statikus dinamikus akt_elem^.adat := 42; akt_elem^.kov:= NIL;
Egy mutató deklarálása (a Heap egy címére mutat) ? Var elso:lista; {egy mutató} Megjegyzés: az elsonincs inicializálvaés egy ismeretlen helyre mutat(“szemét”-re). Főprogramelso
A lista első elemének létrehozása ? New(elso); {az elso-nek hely foglalódik a Heap-ben, de a mezők értékeit még be kell állítanunk} Főprogramelso
Az adat mező feltöltése ? elso^.adat :=42; A ^ operátor a pointer által mutatott helyen levő adattípusra hivatkozik a heap-ben. 42 Főprogramelso
Egy második elem létrehozása ? elso^.adat:= 42; new(elso^.kov); A “.” operátor a record egy mezőjét éri el. 42 Főprogramelso
A láncolt listát lezárjuk elso^.kov^.adat:= 91; elso^.kov^.kov:= NIL; A lista végéta NIL-lel jelezzük. 42 91 NIL Főprogramelso
Az első elem törlése Egy segédváItozó felhasználásával töröljük a lista első elemét(p ugyanolyan típusú, mint elso). p:=elso; elso:= elso^.kov; dispose(p); 42 91 NIL Főprogram elso p
Új listaelem beszúrása a lista végére, ha a lista elejére van mutató és a lista nem üres 4 17 42 p := elso; while p^.kov<> NIL do p:=p^.kov; new(uj); uj^.adat:=20; uj^.kov:=NIL; p^.kov:=uj; NIL elso p 20 NIL uj {p a segéd, ugyanolyan típusú, mint elso} {p-t elvisszük a lista utolsó eleméhez} {uj ugyanolyan típusú, mint elso}
Új listaelem beszúrása a lista elejére, ha a lista elejére van mutató és a lista nem üres 20 4 17 42 new(uj); uj^.adat:=20; uj^.kov:= elso; elso:=uj; NIL uj elso {uj ugyanolyan típusú, mint elso}
Új listaelem beszúrásaa listába, adott tulajdonságú elem után, ha a lista elejére van mutató és a lista nem üres 4 17 42 p := elso; while (p^.adat mod 2 =0) and (p^.kov<>NIL) do p:=p^.kov; if p^.adat mod 2 <>0 then begin new(uj); uj^.adat:=20; uj^.kov:=p^.kov; p^.kov:=uj; end; NIL 20 elso p uj {a p-vel a keresett tulajdonságú elemre állunk(a példában az első páratlan szám) } {p-t elvisszük az első páratlan elemhez, vagy ha nincs ilyen a lista végéig} {előfordulhat, hogy nem találtunk páratlan elemet, ezért megvizsgáljuk, hogy a lista végén vagyunk-e a p-vel. Ha p páratlan számnál áll, akkor beszúrunk a p után} Mi történik, ha a listában az első páratlan szám az utolsó elem? Vezesd le lapon magadnak !!!
Lista első elemének törlése, ha a lista elejére van mutató és a lista nem üres 4 17 42 q := elso; elso:=elso^.kov; dispose(q); NIL elso q Törlésnél érvényes szabályok • egy segédmutatóval mindig a törlendő elemhez állunk, egy másikkal pedig a törlendő elem elé (a példában q-vel az első elemre állunk) • a többi mutatót mind átkapcsoljuk • felszabadítjuk a q-vel mutatott elem által elfoglalt tárhelyet
Adott tulajdonságú elem törlésea listából, ha a lista elejére van mutató és a lista nem üres 4 17 20 42 p := elso; while (p^.kov^.adat <> 20) and (p^.kov^.kov<>NIL) do p:=p^.kov; if p^.kov^.adat =20 then begin q:=p^.kov; p^.kov:=q^.kov; dispose(q); end; NIL elso p q { feltételezzük, hogy nem az első elemet kell törölni q-val a keresett tulajdonságú elemre állunk, p-vel pedig a törlendő elem elé (a példában az első 20-as szám) } {p-t elvisszük az első 20-as elem elé, vagy ha nincs ilyen a lista utolsó előtti eleméig} {előfordulhat, hogy nem találtunk 20-as elemet, ezért megvizsgáljuk, hogy a lista végén vagyunk-e a p következőjével. Ha p következője 20-as számnál áll, akkor törlünk a p után} Mi történik, ha nincs a listában a 20-as érték?
Adott tulajdonságú elem törlésea listából, ha a lista elejére van mutató és a lista nem üres (kicsit másképp) 4 17 20 42 p := elso; q := p^.kov; while (q^.adat <> 20) and (q^.kov<>NIL) do begin p:=p^.kov; q:=q^.kov; end; if q^.adat =20 then begin p^.kov:=q^.kov; dispose(q); end; NIL elso p q feltételezzük, hogy nem az első elemet kell törölni q-val a keresett tulajdonságú elemre állunk, p-vel pedig a törlendő elem elé (a példában az első 20-as szám) {p-t és q-t egyszerre mozgatjuk} Mi történik, ha nincs a listában a 20-as érték? Hát, ha a 20-as érték az utolsó a listában? Vezesd le ezeket az eseteket!!!
1. Feladat: Készítsünk duplán láncolt körlistát az alábbi elemekkel: p q NIL NIL NIL NIL p^.kov := q; q^.kov := r; r^.kov := p; NIL NIL r q^.eloz :=p; r^.eloz := q; p^.eloz := r;
2. Feladat: Készítsünk duplán láncolt körlistát két duplán láncolt listából, ha csak az első elemekre van mutató kezdetben. elso1 NIL 1 2 3 4 NIL p:=elso1; while p^.kov<>NIL do p:= p^.kov; q:=elso2; while q^.kov<>NIL do q:= q^.kov; p elso2 NIL 5 6 7 NIL q p^.kov:=elso2; elso2^.eloz :=p; q^.kov := elso1; elso1^.eloz :=q;
3. Feladat: Egy duplán láncolt dinamikus listában pontosan négy elem található, a p változó az első, a q pedig az utolsó listaelem címét tárolja. Cseréljük fel a 2. és a 3. elemet a megfelelő mutatók átkapcsolásával. NIL 2 1 4 NIL r r:=p^.kov; s:=q^.eloz; p q 3 s Segédváltozókat (r, s) vezetünk be, így könnyebb felírni a mutatók átkapcsolását. p^.kov:=s; s^.kov:=r; r^.kov:=q; q^.eloz :=r; r^.eloz :=s; s^.eloz :=p;
Linkek • http://www.prog.ide.sk/pas2.php?s=48 • http://www.prog.ide.sk/pas2.php?s=50 • http://www.prog.ide.sk/pas2.php?s=52 • http://en.wikipedia.org/wiki/Linked_list Köszönöm a figyelmet!!