Algoritmusok és adatszerkezetek I. 2. előadás
Verem Verem= speciális sorozattípus Műveletei: Üres, üres?, Verembe, Veremből, tető Üres: Verem üres?(verem): Logikai tető(verem): Elem {NemDef} Verembe(Verem,Elem): Verem {NemDef} Veremből(Verem,Elem): (Verem Elem) {NemDef} 2/40
Verem A műveletek specifikációja Üres(V): ef:, uf: V=() üres?(v): ef:, uf: üres?=v=() Verembe(V,e): ef: V=W, uf: V=(W,e) Veremből(V,e): ef: V=(W,f), uf: V=W és e=f Megjegyzés: ef nem üres?(v) tető(v): ef: V=(W,f), uf: tető=f Megjegyzés: ef nem üres?(v) 3/40
Verem Megvalósítás folytonos, szekvenciális ábrázolással Verem(Típus TElem): Konstans MaxMélység: Egész(???) Típus VeremElem=TElem Változó t: Tömb(1..MaxMélység: VeremElem) teteje: 0..MaxMélység Probléma: MaxMélység=???? 4/40
Verem Eljárás Üres(V): V.teteje:=0 Függvény üres?(v): üres?:=v.teteje=0 Függvény vége. Függvény tető(v): tető:=v.t(v.teteje) Függvény vége. 5/40
Verem Eljárás Verembe(V,e): V.teteje:=V.teteje+1 V.t(V.teteje):=e Eljárás Veremből(V,e): e:=v.t(v.teteje) V.teteje:=V.teteje-1 Meggondolandó: hibakezelés hol és mikor kell? 6/40
Verem Megvalósítás dinamikus láncolással Verem(Típus TElem): Típus VeremElem=Rekord(érték: TElem alatta: VeremElem'Mutató) Változó teteje: VeremElem'Mutató Magyarázat: a láncolásnak nincs szerepe a hatékonyság szempontjából (nincs beszúrás vagy törlés középen), csak a memória lefoglalási lehetőséget használjuk ki. 7/40
Verem Eljárás Üres(V): V.teteje:=Sehova Függvény üres?(v): üres?:=v.teteje=sehova Függvény vége. Függvény tető(v): tető:=tartalom(v.teteje).érték Függvény vége. Emlékeztető: Eljárás Üres(V): V.teteje:=0 Függvény üres?(v): üres?:=v.teteje=0 Függvény vége. Függvény tető(v): tető:=v.t(v.teteje).érték Függvény vége. 8/40
Verem Eljárás Verembe(V,e): Lefoglal(w,(e,V.teteje)) V.teteje:=w Eljárás Veremből(V,e): Eljárás Verembe(V,e): V.teteje:=V.teteje+1 V.t(V.teteje):=e Eljárás Veremből(V,e): e:=v.t(v.teteje) V.teteje:=V.teteje-1 e:=tartalom(v.teteje).érték; w:=v.teteje V.teteje:=tartalom(V.teteje).alatta Felszabadít(w) A lefoglalás másképpen: Lefoglal(w) tartalom(w).érték:=e tartalom(w).alatta:=v.teteje 9/40
Verem Megvalósítás dinamikus láncolással (hibakezeléssel) Verem(Típus TElem): Típus VeremElem=Rekord(érték: TElem alatta: VeremElem'Mutató) Változó teteje: VeremElem'Mutató hiba: Logikai 10/40
Verem Eljárás Üres(V): V.teteje:=Sehova; V.hiba:=hamis Itt kihasználjuk, hogy a lefoglalás sikertelensége esetén telik be a verem, amit a lefoglalás művelete állít be. Eljárás Verembe(V,e): Lefoglal(w,(e,V.teteje),V.hiba) V.teteje:=w 11/40
Verem Függvény tető(v): Ha v.teteje=sehova akkor V.hiba:=igaz különben tető:=tartalom(v.teteje).érték Függvény vége. Eljárás Veremből(V,e): Ha v.teteje=sehova akkor V.hiba:=igaz különben e:=tartalom(v.teteje).érték w:=v.teteje V.teteje:=tartalom(V.teteje).alatta Felszabadít(w) 12/40
Verem Speciális verem műveletek a FORTH nyelvből swap(v): a két felső elem cseréje ef: V=(W,e,f), uf: V=(W,f,e) dup(v): a felső elem duplikálása ef: V=(W,e), uf: V=(W,e,e) over(v): a felső alatti elem duplikálása a verem tetején ef: V=(W,e,f), uf: V=(W,e,f,e) rot(v): a felső három elem ciklikus léptetése ef: V=(W,e,f,g), uf: V=(W,f,g,e) 13/40
Verem Eljárás swap(v): e:=tartalom(v.teteje).érték w:=tartalom(v.teteje).alatta tartalom(v.teteje).érték:=tartalom(w).érték tartalom(w).érték:=e 14/40
Verem Eljárás dup(v): e:=tartalom(v.teteje).érték Lefoglal(w,(e,V.teteje)) V.teteje:=w 15/40
Verem Eljárás over(v): w:=tartalom(v.teteje).alatta e:=tartalom(w).érték Lefoglal(w,(e,V.teteje)) V.teteje:=w 16/40
Verem Eljárás rot(v): w:=tartalom(v.teteje).alatta x:=tartalom(w).alatta e:=tartalom(x).érték tartalom(x).érték:=tartalom(w).érték tartalom(w).érték:=tartalom(v.teteje).érték tartalom(v.teteje).érték:=e 17/40
Verem alkalmazás Egy kifejezés (,) és [,] zárójelpárokat tartalmaz. Ellenőrizzük a helyességét! Hibás esetek: x([y)] hibás párosítás x(a - nyitó zárójelnek nincs csukó párja x)a( - csukó zárójelnek nincs nyitó párja 18/40
Verem alkalmazás Függvény helyes(k): i:=1; h:=igaz; V:=üres Ciklus amíg i hossz(k) és h Ha K(i)= ( vagy K(i)= [ akkor Verembe(V,K(i)) különben ha K(i)= ) vagy K(i)= ] akkor Veremből(V,s) h:= K(i)= ) és s= ( vagy K(i)= ] és s= [ i:=i+1 Ciklus vége helyes:=h és nem V.hiba és üres?(v) 19/40
Sor Sor= speciális sorozattípus Műveletei: Üres, üres?, Sorba, Sorból, első Üres: Sor üres?(sor): Logikai első(sor): Elem {NemDef} Sorba(Sor,Elem): Sor {NemDef} Sorból(Sor,Elem): (Sor Elem) {NemDef} 20/40
Sor A műveletek specifikációja Üres(S): ef:, uf: S=() üres?(s): ef:, uf: üres?=s=() Sorba(S,e): ef: S=W, uf: S=(W,e) Sorból(S,e): ef: S=(f,W), uf: S=W és e=f Megjegyzés: ef nem üres?(s) első(s): ef: S=(f,W), uf: első=f Megjegyzés: ef nem üres?(s) 21/40
Sor Megvalósítás folytonos, szekvenciális ábrázolással Sor(Típus TElem): Konstans MaxHossz: Egész(???) Típus SorElem=TElem Változó t: Tömb(1..MaxHossz: SorElem) első,utolsó,db: 0..MaxHossz A tömböt ciklikusan kezeljük: ha a végére értünk és az elején már szabadult fel hely, ott folytatjuk a kitöltést. Probléma: MaxHossz=???? 22/40
Sor Eljárás Üres(S): S.első:=1; S.utolsó:=0; S.db:=0 Függvény üres?(s): Üres?:=S.db=0 Függvény vége. Függvény első(s): első:=s.t(s.első) Függvény vége. 23/40
Sor Eljárás Sorba(S,e): Ha S.utolsó=Maxhossz akkor S.utolsó:=1 különben S.utolsó:=S.utolsó+1 S.db:=S.db+1; S.t(S.utolsó):=e Eljárás Sorból(S,e): e:=s.t(s.első); S.db:=S.db-1 Ha S.első=Maxhossz akkor S.első:=1 különben S.első:=S.első+1 S.utolsó S.első 24/40
Sor Megvalósítás dinamikus láncolással Sor(Típus TElem): Típus SorElem=Rekord(érték: TElem köv: SorElem'Mutató) Változó eleje,vége: SorElem'Mutató Megjegyzés: Itt sem használunk középre beszúrást, középről törlést, azaz a láncolást csak a tömbméret korlát elhagyása miatt használjuk. 25/40
Sor Eljárás Üres(S): S.eleje:=sehova; S.vége:=sehova Függvény üres?(s): Üres?:=S.eleje=sehova Függvény vége. Függvény első(s): első:=tartalom(eleje).érték Függvény vége. Emlékeztető: Eljárás Üres(S): S.első:=1; S.utolsó:=0 S.db:=0 Függvény üres?(s): Üres?:=S.db=0 Függvény vége. Függvény első(s): első:=s.t(s.első) Függvény vége. 26/40
Sor Eljárás Sorba(S,e): Lefoglal(újvége,(e,sehova)) Ha S.vége=sehova akkor S.eleje:=újvége különben tartalom(s.vége).köv:=újvége S.vége:=újvége 27/40
Sor Eljárás Sorból(S,e): e:=tartalom(s.eleje).érték újeleje:=tartalom(s.eleje).köv Felszabadít(S.eleje) S.eleje:=újeleje Ha S.eleje=sehova akkor S.vége:=sehova 28/40
Sor Megvalósítás dinamikus láncolással (hibakezeléssel) Sor(Típus TElem): Típus SorElem=Rekord(érték: TElem köv: SorElem'Mutató) Változó eleje,vége: SorElem'Mutató hiba: Logikai 29/40
Sor Eljárás Üres(S): S.eleje:=sehova; S.vége:=sehova; S.hiba:=hamis Függvény első(s): Ha S.eleje=sehova akkor S.hiba:=igaz különben első:=tartalom(s.eleje).érték Függvény vége. 30/40
Sor Eljárás Sorba(S,e): Lefoglal(új,(e,sehova),S.hiba) Ha S.vége=sehova akkor S.eleje:=új különben tartalom(s.vége).köv:=új S.vége:=új 31/40
Sor Eljárás Sorból(S,e): Ha S.eleje=sehova akkor S.hiba:=igaz különben e:=tartalom(s.eleje).érték újeleje:=tartalom(s.eleje).köv Felszabadít(S.eleje) S.eleje:=újeleje Ha S.eleje=sehova akkor S.vége:=sehova 32/40
Sor alkalmazás Példa: Egy vasútvonal két állomásán egy nap feljegyeztük, az összes egyik irányba áthaladó vonat indulási, illetve érkezési idejét (idő szerinti sorrendben). Adjuk meg az áthaladt vonatok menetidőit a két állomás között! (Nincs előzés.) Ötlet: A korábban érkező adatot egy sorban várakoztatjuk addig, amíg a párja meg nem érkezik. 33/40
Sor alkalmazás Forgalom: Nyit(f); Nyit(g); Üres(S) Ciklus amíg nem vége?(f) Olvas(f,adat) Ha adat.állomás=1 akkor Sorba(S,adat.idő) különben Sorból(S,előző) Ír(g,adat.idő-előző) Ciklus vége Zár(f); Zár(g) 34/40
Sor alkalmazás Példa: Egy egyirányú utcában két jelzőlámpánál figyelik az áthaladó autókat: mikor haladt át a lámpánál. Az adatok megfigyelési idő szerinti sorrendben érkeznek. N db autót figyeltek meg. Csoportosítsuk az adatokat, hogy az első lámpánál történt megfigyelések időbeli sorrendjüket megtartva előzzék meg a második lámpánál megfigyelt adatokat! (Az utcában előzés nincs.) Ötlet: Az 1-es lámpa adatai azonnal írhatók az eredménybe, a 2-es lámpa adatait egy átmeneti sorban tároljuk, s a végén írjuk az eredménybe. A sor ha a mérete indokolja persze lehet háttértáron is. 35/40
Sor alkalmazás Ötlet: Az 1-es lámpa adatai azonnal írhatók az eredménybe, a 2- es lámpa adatait egy átmeneti sorban tároljuk, s a végén írjuk az eredménybe. A sor ha a mérete indokolja persze lehet háttértáron is. A bemenet és a kimenet is forgalom típusú adatok fájlja, és a sorban is ilyeneket tárolunk: Forgalom=Rekord(lámpa: {1,2}, idő: Egész) Változó S: Sor(Forgalom) 36/40
Sor alkalmazás Forgalom: Nyit(f); Nyit(g); Üres(S) Ciklus amíg nem vége?(f) Olvas(f,adat) Ha adat.lámpa=1 akkor Ír(g,adat) különben Sorba(S,adat) Ciklus vége Ciklus amíg nem üres?(s) Sorból(S,adat); Ír(g,adat) Ciklus vége Zár(f); Zár(g) 37/40
Kétvégű sor Kétvégű sor= speciális sorozattípus Műveletei: Üres, üres?, Sorelejére, Sorvégére, első, Sorelejéről, Sorvégéről Üres: Sor Sorelejére(Sor,Elem): Sor {NemDef} Sorvégére(Sor,Elem): Sor {NemDef} Sorelejéről(Sor,Elem): (Sor Elem) {NemDef} Sorvégéről(Sor,Elem): (Sor Elem) {NemDef} üres?(sor): Logikai első(sor): Elem {NemDef} 38/40
Kétvégű sor A műveletek specifikációja Üres(S): ef:, uf: S=() üres?(s): ef:, uf: üres?=s=() Sorelejére(S,e): ef: S=W, uf: S=(e,W) Sorvégére(S,e): ef: S=W, uf: S=(W,e) Sorelejéről(S,e): ef: S=(f,W), uf: S=W és e=f Sorvégéről(S,e): ef: S=(W,f), uf: S=W és e=f első(s): ef: S=(f,W), uf: első=f 39/40
Algoritmusok és adatszerkezetek I. 2. előadás vége