Adatszerkezetek Listák Dr. Iványi Péter 1
Láncolt lista Akkor használjuk ha a már tárolt adatok közé kell beszúrni új adatokat vagy A meglevő adatok közül kell törölni Egy lista elem két mezőből áll: A tárolandó adat Egy mutató Mindig van egy lista fej List első elemére mutat Ha nincs elem, speciális elemre mutat: 2
Egyirányú láncolt lista A listában szereplő elemek láncot alkotnak Lista utolsó eleme: a mutató Példa lista: listafej listafej Üres lista: 1.elem 2.elem 3.elem 3
Egyirányú láncolt lista A lista elemeit csak úgy érhetjük el, hogy a fejtől indulva végigmegyünk a lista elemein és minden elem feldolgozása után a következő elemre ugrunk.o(n) komplexitás Egy elem egy rekord: adat mező: maga a tárolandó adat kovetkezo mező: a következő elem a listában adat kovetkezo 4
Lista bejárása, kiírása függvény lista_kiírása i = listafej ciklus i <> ki: i adat i = i kovetkezo ciklus vége függvény vége : rekordbeli mezőre hivatkozás 5
Lista kiírása 1. i = listafej Kiírás: 1. Elem 1.elem 2.elem 3.elem 6
Lista kiírása 2. listafej 1.elem i Kiírás: 1. Elem 2. Elem 2.elem 3.elem 7
Lista kiírása 3. listafej 1.elem Kiírás: 1. Elem 2. Elem 3. Elem 2.elem i 3.elem 8
Lista kiírása 4. listafej 1.elem Kiírás: 1. Elem 2. Elem 3. Elem 2.elem 3.elem i 9
Elem beillesztése1. függvény elem_beilleszt be:elem elem kovetkezo = listafej kovetkezo listafej kovetkezo = elem függvény vége elem listafej 2.elem 1.elem 3.elem 10
Elem beillesztése2. elem kovetkezo = listafej kovetkezo elem listafej 2.elem 1.elem 3.elem 11
Elem beillesztése3. listafej kovetkezo = elem elem listafej 2.elem 1.elem 3.elem 12
Elem beillesztése4. listafej 2.elem 1.elem 3.elem 13
Elem keresése függvény keresés be: elem i = listafej ciklus (i <> ÉS i adat <> elem) i = i kovetkezo ciklus vége ha i <> akkor ki: i különben ki: nem létezik a listában elágazás vége függvény vége O(n) 14
Elem törlése 1. függvény elem_torles be: elem elozo = i = listafej ciklus (i <> ÉS i adat <> elem) elozo = i i = i kovetkezo ciklus vége ha i <> akkor elozo kovetkezo = i kovetkezo elágazás vége függvény vége O(n) 15
Elem törlése 2. listafej elozo elem = 2. elem 1.elem i 2.elem 3.elem 16
Elem törlése 3. elozo kovetkezo = i kovetkezo listafej elozo 1.elem i Mi lesz ezzel? 2.elem 3.elem 17
Lista kezelés Alistakezelő rendszerben általában két listát tartunk 1. A foglalt elemek listája 2. A szabad elemek listája Egy elem törlése azt jelenti, hogy a szabad listába tesszük át az elemet!!! 18
Lista kezelés 1. Szabad lista Új lista F F N N 19
Lista kezelés, beillesztés 1. Szabad lista F Új lista F N N 20
Lista kezelés, beillesztés 1., másképp Szabad lista F Új lista F N N 21
Lista kezelés, beillesztés 2. Szabad lista F Új lista F N N 22
Lista kezelés, beillesztés 3. Szabad lista F Új lista F N N 23
Lista kezelés, törlés 1. Szabad lista F Új lista F N N 24
Listák és tömbök Tömb: véletlen elérés (random access) Lista: Szekvenciális elérés Művelet Beillesztés Törlés a végéről Tömb O(n) O(1) Lista O(1) O(n) 25
Listák és tömbök Josephus probléma (demonstrálja a különbséget) Flavius Josephus Első századbeli történész Ő és 40 ember egy barlangban ragadt, rómaiak által körülvéve Az öngyilkosságot választották a fogság helyett Kiválasztják ki öl meg kit Josephus és még egy ember maradt meg Josephus rávette a másikat hogy adják meg magukat 26
Választási probléma Josephus probléma n darab ember körbe áll Valahol elkezdve a k-adik embert kivégzik Ezután a k-1 -edik embert végzik ki Stb 27
Listák és tömbök Az emberek a lista csomópontjai Mutatja, hogy milyen könnyű egy elemet törölni Mennyire nehéz egy elemet megtalálni, végig kell menni a többi elemen Tömb esetén Nehéz törölni A többi elemet előre kell tolni Könnyű az n-edik elemet megtalálni Csak a pozíció indexét kell használni 28
Kétirányú lista listafej adat 1 adat 2 Elejétől vagy végétől is be lehet járni a listát. Egyszerű a beillesztés a lista elejére vagy végére adat 3 29
Körkörös listák listafej 1.elem 3.elem 2.elem 30
Körkörös listák listafej 1.elem 2.elem 3.elem 31
Lista mutató nélkül Nem minden nyelv támogatja a mutatókat Tömböt is használhatunk szimulációként A tömb minden eleme egy rekord record Entry { integer next; // a következő elem integer prev; // az előző elem string name; real balance; } 32
Lista mutató nélkül Index Next Prev Name Balance 0 1 4 Kovács I. 111 1-1 0 Kiss B. 2341 2(fej) 4-1 Nagy S. 34 3 Horváth E. 745 4 0 2 Lovas G. 9657 5 6 3., 5., 6. elemek nem részei a listának Szabad elemek indexeiből egy másik tömböt lehet csinálni 33
Lista nyomtatása függvény lista_kiírása i = fej ciklus i > 0 ki: i, tomb[i].name, tomb[i].balance i = tomb[i].next ciklus vége függvény vége 34
Külső-belső adatok Egy lista elem két mezőből áll: A tárolandó adat Egy mutató A kérdés, hogy az adatot az elemben vagy azon kívűl tároljuk?? Internal storage External storage 35
Belső adatok listafej 1.elem 2.elem 36
Belső adatok Az adatelérés hatékonyabb Egyszerűbb memória kezelés Kevesebb memória foglalásra van szükség A csomóponttal egy időben végezzük az adatok lefoglalását 37
Külső adatok listafej 1.elem 2.elem 38
Általánosabb Külső adatok Ugyanaz az adatszerkezetet lehet használni különböző adatokkal Bonyolultabb memória kezelést igényel 39
Adatok keresése Általános esetben a keresés: O(n) Hogyan lehet hatékonyabbá tenni? Sorba rendezett lista Move-to-front heurisztika A megtalált elemet a lista elejére helyezzük A legutoljára használt elemet lehet a leggyorsabban megtalálni Más adatszerkezetet használunk az indexelésnél, melyben könnyebb keresni: Fák Hasító táblák 40
Alkalmazás A LISP és Scheme nyelveknél az alap adatszerkezet az egyirányú lista Funckionális nyelvek A listát csomópontokból építjük fel Egy csomópontnak két része van car: a csomópont adatszerkezete cdr: mutató a következő elemre 41
Programozási nyelvek osztályozása Procedurális nyelvek Kifejezések sorozatát hajtjuk végre mely valamilyen eredményhez vezet Változókat, ciklusokat használunk Program állapotok Funkcionális nyelvek Nem igazán használunk tárolt állapotokat Nem ciklusokat hanem rekurziót használunk Függvényeket hívunk és a visszatérési értékeket használunk Változók módosítása mellékhatás! 42
Lisp programozási nyelv Kifejlesztése: 1960-ban, John McCarthy, Massachusetts Institut of Technology LISt Processing Lista feldolgozás Fortran nal egyidős Szakértői rendszerekben, mesterséges intelligencia kutatásban használj(t)ák Programozható programnyelv -ként is szokták definiálni 43
Lisp és a grafikus rendszerek Objektum modellező és CAD rendszerek Allegro Solid + Common Lisp ACIS + Scheme AutoCAD + AutoLisp Repülőgépjegy foglalási rendszer Üzleti döntéshozó rendszerek 44
ABUSE játék 45
Mesterséges intelligencia Tudás reprezentálás Harold Cohen művész programja: AARON 46
AutoCAD programozása AutoCAD egy alap CAD rendszer A CAD rendszer szinte minden aspektusa módosítható ActiveX Visual Basic AutoLisp és Visual Lisp ObjectARX Menük módosítása DIESEL szöveg processzálás, pl. státusz sor 47
ObjectARX void chngatt() { ads_name entres; ads_point ptres; AcDbObjectId _Id, _attid; AcDbObjectIterator *pittr = NULL; if(acedentsel("select a Block Reference", entres, ptres)!= RTNORM ) { //Selection failed return; } acdbgetobjectid(_id, entres); AcDbObjectPointer pref(_id,acdb::kforread); if(pref.openstatus()!=acad::eok) { //Open failed return; } 48
ObjectARX } pittr = pref->attributeiterator(); while(!pittr->done()) { _attid = pittr->objectid(); AcDbObjectPointer patt(_attid,acdb::kforwrite); if(patt.openstatus()==acad::eok) { patt->settextstring("we changed this"); break; } pittr->step(); } delete pittr; 49
Visual Basic Option Explicit Sub chngatt() Dim objent As AcadObject Dim objref As AcadBlockReference Dim varatts As Variant Dim objatt As AcadAttributeReference Dim emptypt As Variant ThisDrawing.Utility.GetEntity objent, emptypt, "Select Block: If objent.objectname = "AcDbBlockReference" Then Set objref = objent If objref.hasattributes Then varatts = objref.getattributes Set objatt = varatts(0) objatt.textstring = "We changed this" End If End If End Sub 50
AutoLisp (defun C:chngAtt (/ Mainent entlist entatt entnewattval) (setq Mainent (entsel)) (setq entlist (entget (car Mainent))) (setq entatt (entget (entnext (cdr (assoc -1 entlist))))) (setq entnewattval (subst (cons 1 "We changed this") (assoc 1 entatt) entatt) ) (entmod entnewattval) (entupd (car Mainent)) (princ) ) 51
Lisp Language of Infinite Stupid Parantheses (megszámlálhatatlan ostoba zárójelek nyelve) ; megjegyzés (elem1 (elem2 (elem3 elem4) (elem5 (elem6. elem7)) ) ) 52
Lisp alapelemek A nyelv programok és adatok leírására egyetlen szerkezetet használ, a John Carthy által kidolgozott szimbólikus kifejezéseket, S- kifejezéseket. 53
Lisp alapelemek Alapelemek: Listák Atomok sorozata zárójelek között Atomok Definíció: minden ami nem lista, a nyelv eszközeivel nem bontható tovább Konstans atomok Szimbólikus atomok 54
Kiértékelés LISP = Lista feldolgozás Feldolgozás folyamata = kiértékelés AutoLISP egy interpretált nyelv Interpreter szíve az evaluator = kiértékelő, értelmező A felhasználó interaktív módon párbeszédet folytat az értelmezőprogrammal. 55
Kiértékelési ciklus 1. Az értelmező program beolvas egy S-kifejezést 2. A kifejezést kiértékeli meghatározza a kifejezés értékét mintha függvény lenne lehetnek mellékhatások 3. A kifejezés értékét kiírja, majd kezdi az 1. ponttól 56
Kiértékelési ciklus A három lépésnek megfelel egy-egy LISP függvény: READ, EVAL, PRINT Ezért nevezik ezt a végtelen ciklust: read-eval-print ciklusnak 57
Kiértékelés sorrendje 1. Konstans atom értéke: maga az atom 2. Szimbólikus atom értéke: a szimbólumhoz rendelt értéke 3. Lista esetén függvényként értékeli ki 58
Lisp függvények A függvények általános formája: (művelet A... B) így sohasem kérdés hogy melyik művelet hajtódik végre először Ellentétben a matematikai kifejezéssel: 3 + 5 * 4 amit csak megfelelő gyakorlás után tudunk megoldani: először a szorzást majd az összeadást hajtjuk végre 59
Kezdjünk el programozni! Az egyik legegyszerűbb számítógép a zsebkalkulátor Egyszerű számítási műveletek: (+ 5 5) (+ -5 5) (+ 5-5) (- 5 5) (* 3 4) (/ 8 12) 60
Függvény lista kiértékelése A kiértékelés balról jobbra történik Először az argumentumokat értékeli ki, majd a teljes kifejezést A kiértékelés eredménye is egy kifejezés: atom vagy lista!!! Mivel az adat lista és a függvény lista azonos ezért megvalósítja a Neumann elvet: adat és program nem különböztethető meg 61
Műveletek egymásba ágyazása Egy művelet argumentuma lehet szám vagy egy másik művelet. Egymásbaágyazás esetén először a legbelső zárójel közötti részt redukáljuk számmá, majd a követkető szintet és így tovább. 62
Példa (* (+ 2 2) (/ (* (+ 3 5) (/ 30 10)) 2)) = (* 4 (/ (* 8 3) 2)) = (* 4 (/ 24 2)) = (* 4 12) = 48 63
Infixből Postfixbe konverzió Infix Postfix A*B+C A B * C + A+B*C A B C * + A*(B+C) A B C + * (A+B)*C A B + C * 64
A*B+C vége OpStack Postfix 65
A OpStack Postfix a 66
* OpStack Postfix a * 67
B OpStack Postfix a * b 68
1. + OpStack Postfix a * b 69
2. + OpStack Postfix a b * 70
3. + OpStack Postfix a + b * 71
C OpStack Postfix a + b * c 72
1. vége OpStack Postfix a + b * c 73
2. vége OpStack Postfix a b * c + 74
A*B+C OpStack Postfix a b * c + 75
Házi feladat Írjunk programot mely megfordítja az elemek sorrendjét. Írjunk programot amely megszámolja a listában előforduló elemek számát! 76