Láncolt lista
Listák¶
Ahogy azt láthattuk, a tömb egy igen hatékony eszköz akkor, amikor adott elemtípusú elemek sokaságát kell eltároljuk. Ezzel az adatszerkezettel hatékonyan tudjuk elérni a tömbben tárolt adatokat. Azonban ha sokszor kell törölnünk és beszúrnunk elemeket a tömbbe, látni fogjuk, hogy ez tömbök esetében nem annyira hatákony, különösen ha a tömb mérete nagy.
Az ilyen esetekben lehet megoldás a Lista adatszerkezet.
Listák esetében az elemek elérése persze nem lesz annyira triviális, mint a tömböknél, itt egy aktuális elemet tudunk kijelölni, amely elemtől be tudjuk járni a teljes listát. Neve
Lista, mint absztrakt adattípus¶
Jelöljük az \(elemtip\) alaptípusból képzett Lista típust \(lista\)-val, és a lista egy helyét meghatározó típust \(pozicio\)-val.
Egy listát a következő műveletek határoznak meg:
Művelet megnevezése | Művelet leírása |
---|---|
Létesít(\(\leftarrow\) l :lista ) |
Egy üres lista létesítése és visszaadása az l változóban. |
Megszüntet(\(\leftrightarrow\) l :lista ) |
Az l lista megszüntetése. |
Kiolvas(\(\rightarrow\) p:pozicio; \(\leftarrow\) x :elemtip ) |
A p pozíción lévő érték kiolvasása adott x , elemtip típusú változóba. |
Módosít(\(\rightarrow\) p:pozicio; \(\rightarrow\) x :elemtip ) |
A p pozíción lévő eleme értékének módosítása x -re. |
Beszúr(\(\leftrightarrow\) l:lista; \(\rightarrow\) p:pozicio; \(\rightarrow\) x :elemtip ) |
Az adott l listába a p pozíció elé szúrjuk be az x értéket. |
Töröl(\(\leftrightarrow\) l:lista; \(\rightarrow\) p :pozicio ) |
Töröljük az l lista p pozícióján lévő elemét. |
Következő(\(\rightarrow\) l:lista; \(\rightarrow\) p:pozicio; \(\leftarrow\) n :pozicio ) |
Az l lista p pozícióját követő pozíciót adja vissza n -ben. |
Értékadás(\(\leftarrow\) lhs :lista ; \(\rightarrow\) rhs :lista ) |
Értékadó művelet: az lhs változó felveszi az rhs kifejezés értékét. |
Láncolt lista, virtuális adattípus¶
A lista egy megvalósítása lehet a láncolt lista, ahol a lista elemeit egymás után láncoljuk. Minden elem ismeri a lista következő elemet (esetleg az előzőt is), illetve adott a lista első eleme, amelytől elindulva bejárhatjuk a listát. Az elérési információ általában egy pointerrel adott, amely a következő elemre, mint dinamikus változóra hivatkozik.
Egy adott elem megkeresése persze nehézkes lehet, de új elemet felvenni, vagy meglevőt törölni relatív kis költséggel lehet.
A műveleteket most is absztrakt módon írjuk le egy külön headerben (lanc_t.h
), megadva mellette a listát leíró adatszerkezetet:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
A konkrét megvalósítás láncolt lista esetében pedig:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
|
Láncok bejárására írhatunk olyan függvényt amelynek paramétere az elvégzendő művelet:
1 2 3 4 5 6 7 8 |
|
Ezzel a módszerrel a megvalósítás egyes technikai részleteit jobban elkülöníthetjük, érthetőbbé, átláthatóbbá, könnyen módosíthatóbbá válik a kódunk.
Ha például adatszerkezetet cserélünk, a bejárását elegendő abejar()
függvényben egyetlen helyen átírni, hogy a program továbbra is jól működjön.