Upload
komala
View
61
Download
0
Embed Size (px)
DESCRIPTION
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, - PowerPoint PPT Presentation
Citation preview
RekordokDinamikus tárkezelés és pointerek
Dinamikusan láncolt listák
Ismétlés: Rekordok
Rekordok rekordokon 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;
Ez az azonosító mostantól egy
típus, amit bárhol felhasználhatunk, mint pl. a “word”
típust.
Minek nevezzük ezeket?
Típusok
Rekordok rekordokon belül
datum_tipus:
diak_tipus:
Var bob: diak_tipus;
bob.szul_nap.honap := 6;
nap honap ev
nap honap ev
nev osztaly
nap honap evszul_nap
erettsegi_nap
Típusok vagy változók
• Típusdefiníciók (TYPE)– Új típusokat hozunk 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öre korlá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ár létező adattípussal használható
Dinamikus tárkezelés és pointerek
Dinamikus kontra 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énk növelni vagy csökkenteni
az adatszerkezeteink méretét, hogy megfeleljenek a feladat követelményeinek.
Statikus adatok
• Statikus adatok a program futása előtt deklará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.
Dinamikus adatok
• Dinamikus adatok idő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 pontosan annyi 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
akarjuk a memóriát.• És tesszük ezt a program futása közben.
Példák:Nyomtató várakozási soraRepülésirányító....akármi más ?, adj példát
Példák:Nyomtató várakozási soraRepülésirányító....akármi más ?, adj példát
A memória szerkezete egy program esetén
Kódszegmens(a program forráskódját
tartalmazó modul)
Verem (Statikus Rész)(felfelé foglal új helyet)
Heap (Kupac) (Dinamikus Rész)
(lefelé foglal új helyet)
A Heap (kupacmemória)
Főprogram egy_változó más_változó ptr4 7
12
•A heap a memóriának egy része, ahol a dinamikus tárkezelés megvalósul•A statikus változók az adatszegmensben vagy a veremszegmensben kapnak helyet (ezek is a memóriának részei)
Ez milyen típusú változó???
Heap
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
Főprogram p
• Mikor “követünk egy mutatót”, azt mondjuk elvonatkoztatunk az illető pointertől
• A kalap (^) jelentése “a pointernél levő adat”• p^ jelentése ”kövesd, hogy a p mire mutat”• p^:=43; érvényes értékadás
Heap: dinamikus
Adatsz.: Statikus
Var P,Q:^word;new(P);P^:= 5;Q:= P;writeln(P^, Q^);Q^ := 7;writeln(P^, Q^);
word típus
5 55 57 7
P
Pointer
Q
Pointer
57
Pointer Animation of Numbers
statikus dinamikus
Képernyőn:
Egy record, amely két adatot fog tárolni - egy nevet és egy személyi számot (CNP) :
Type diak = record
nev : String[20];
CNP : longint;
end;
Egy mutató (pointer) egy diak rekordhoz:Var pdiak : ^diak;
New(pdiak);
nev
CNP
Pointerek és rekordok
pdiakBob
123456789
statikus dinamikus
pdiak
pdiak
pdiak^
Bob
123456789
statikus dinamikus
Pointerek és rekordok
pdiak
pdiak^.nev := ’Bob’;
Bob
123456789
statikus dinamikus
Pointerek és rekordok
pdiak
pdiak^.CNP := 123456789;
Bob
123456789
statikus dinamikus
Pointerek és rekordok
Láncolt listák
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, mert nem 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áncolt listák
Mutatók (pointerek) segítségével az adatokat ö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}
Mutatók és láncolt listák
akt_elem
akt_elem^
akt_elem ^.kov
akt_elem ^.adat
statikus dinamikus
Egy listaelem mezőinek elérése
akt_elem
akt_elem^.adat := 42;
akt_elem ^.kov := NIL;
42
statikus dinamikus
NIL
Egy mutató deklarálása (a Heap egy címére mutat)
Var elso: lista; {egy mutató}
Megjegyzés: az elso nincs inicializálva és egy ismeretlen helyre mutat (“szemét”-re).
Főprogram elso
?
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őprogram elso
?
Az adat mező feltöltése
elso^.adat := 42;
A ^ operátor a pointer által mutatott helyen levő adattípusra hivatkozik a heap-ben.
Főprogram elso
?42
Egy második elem létrehozása
elso^.adat := 42;new(elso^.kov);
A “.” operátor a record egy mezőjét éri el.
Főprogram elso
42 ?
A láncolt listát lezárjuk
elso^.kov^.adat := 91;elso^.kov^.kov := NIL;
A lista végét a NIL-lel jelezzük.
Főprogram elso
42 91
NIL
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);
Főprogram elso p
42 91
NIL
Új listaelem beszúrása a lista végére, ha a lista elejére van mutató és a lista nem üres
p := elso;
while p^.kov<> NIL do
p:=p^.kov;
new(uj); uj^.adat:=20;
uj^.kov:=NIL;
p^.kov:=uj;
4 17 42
NIL
elso p 20uj
NIL
{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
new(uj);
uj^.adat:=20;
uj^.kov:= elso;
elso:=uj;
4 17 42
NILelso
20
uj
{uj ugyanolyan típusú, mint elso}
Új listaelem beszúrása a listába, adott tulajdonságú elem után, ha a lista elejére van
mutató és a lista nem üres
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;
4 17 42
NIL
elso p 20uj
{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
q := elso;
elso:=elso^.kov;
dispose(q);
4 17 42
NIL
elso qTö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ése a listából, ha a lista elejére van mutató és a lista nem üres
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;
4 17 42
NIL
elso p
20
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ése a listából, ha a lista elejére van mutató és a lista nem üres
(kicsit másképp)
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;
4 17 42
NIL
elso p
20
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^.kov := q;
q^.kov := r;
r^.kov := p;
NIL
p
NIL NIL
q
NIL
NIL
r
NIL
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.
p:=elso1; while p^.kov<>NIL do p:= p^.kov;q:=elso2; while q^.kov<>NIL do q:= q^.kov;
elso1
NIL
NIL
p
p^.kov:=elso2;
elso2^.eloz :=p;
q^.kov := elso1;
elso1^.eloz :=q;
NIL NILelso2
q
1 2 3 4
5 6 7
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 .
r:=p^.kov; s:=q^.eloz;
NIL
NIL
p
p^.kov:=s;
s^.kov:=r;
r^.kov:=q;
1
2
3
4
q
Segédváltozókat (r, s) vezetünk be, így könnyebb felírni a mutatók átkapcsolását.
r
s
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!!