86
   Írta:  A DONYI RÓBERT  A DA TSTRUK TÚRÁ K ÉS  A LGORITMUSOK Egyetemi tananyag 2011

Adonyi_Adatstrukturak

Embed Size (px)

DESCRIPTION

Adonyi_Adatstrukturak

Citation preview

  • rta: ADONYI RBERT

    ADATSTRUKTRK S ALGORITMUSOK Egyetemi tananyag

    2011

  • COPYRIGHT: 20112016, Dr. Adonyi Rbert, Pannon Egyetem Mszaki Informatikai Kar Rendszer- s Szmtstudomnyi Tanszk LEKTORLTA: Dr. Fbin Csaba, Kecskemti Fiskola Gpipari s Automatizlsi Mszaki Fiskolai Kar Informatika Szakcsoport Creative Commons NonCommercial-NoDerivs 3.0 (CC BY-NC-ND 3.0) A szerz nevnek feltntetse mellett nem kereskedelmi cllal szabadon msolhat, terjeszthet, megjelentethet s eladhat, de nem mdosthat. TMOGATS: Kszlt a TMOP-4.1.2-08/1/A-2009-0008 szm, Tananyagfejleszts mrnk informatikus, programtervez informatikus s gazdasginformatikus kpzsekhez cm projekt keretben.

    ISBN 978-963-279-488-4 KSZLT: a Typotex Kiad gondozsban FELELS VEZET: Votisky Zsuzsa AZ ELEKTRONIKUS KIADST ELKSZTETTE: Er Zsuzsa

    KULCSSZAVAK: adatstruktra, algoritmus, C, C++, programozs, verem, sor, lncolt lista, grf, fa.

    SSZEFOGLALS: A jegyzet clja, hogy betekintst nyjtsunk a programozsi feladatok sorn elnk kerl programtervezsi krdsekbe. Ehhez bemutatjuk az alap adatszerkezeteket s az adatszerkezeteken megvalsthat klnbz algoritmusokat, hiszen a rendelkezsnkre ll adatszerkezetek s a hozzjuk kapcsold algoritmusok tulajdonsgainak s mkdsknek alapos ismeretben tudjuk csak az alkalmazs ignyeinek legmegfelelbb megoldst kivlasztani. A jegyzet az elmleti ismeretanyagot s a programozs jelleg trgyak teljestshez szksges gyakorlati jelleg tudst kapcsolja ssze. A jegyzetben szerepl mintaprogramok s kdrszletek objektum orientlt szemlletben C++ programozsi nyelven kerlnek megvalstsra.

  • Tartalomjegyzk 3

    Tartalomjegyzk

    Bevezets ............................................................................................................................... 5

    Elfelttelek....................................................................................................................... 5 Programozsi konvencik.................................................................................................. 5 Algoritmus s adat ............................................................................................................. 6 Szoftvertervezs s -fejleszts ........................................................................................... 7 Objektum orientlt programozs ....................................................................................... 7 Szoftvertechnolgia ........................................................................................................... 8

    UML .............................................................................................................................. 9 C++ programozsi nyelv ................................................................................................. 10

    Dinamikus tmb s lncolt lista........................................................................................... 11 Tmb s dinamikus tmb ................................................................................................ 11 Lncolt lista ..................................................................................................................... 12

    Egyszeresen lncolt lista.............................................................................................. 12 Ktszeresen lncolt lista .............................................................................................. 17 Krkrsen lncolt lista............................................................................................... 18 rszemes lista.............................................................................................................. 18 Ritka mtrix trolsa lncolt listval ........................................................................... 18

    Verem adatszerkezet............................................................................................................ 19 Verem implementlsa tmbbel ...................................................................................... 19 Verem implementlsa lncolt listval............................................................................ 21

    Sor adatszerkezet ................................................................................................................. 23 Prioritsos (elsbbsgi) sor adatszerkezet ....................................................................... 26

    Binris fa adatszerkezet ....................................................................................................... 28 Binris fa implementlsa mutatkkal ............................................................................ 29

    Binris fa cscsainak megszmllsa .......................................................................... 30 Binris fa bejrsa ....................................................................................................... 31

    Binris keresfa ............................................................................................................... 33 Piros-fekete s AVL fk .................................................................................................. 36 Kifejezsek trolsa binris fval .................................................................................... 36 Kupac adatszerkezet ........................................................................................................ 37

    Rendezs.............................................................................................................................. 39 Beszrsos rendezs ........................................................................................................ 39 Kivlasztsos rendezs .................................................................................................... 41 Bubork rendezs ............................................................................................................ 42 Kupac rendezs................................................................................................................ 43 Gyorsrendezs ................................................................................................................. 46 sszefslses rendezs .................................................................................................. 48 Lda rendezs .................................................................................................................. 50

    Grfok.................................................................................................................................. 52 Grfok brzolsa ............................................................................................................ 52

    Adjacencia lista s mtrix............................................................................................ 52 Incidencia mtrix ......................................................................................................... 54

    Grf bejrsa.................................................................................................................... 55 Grf mlysgi bejrsa ................................................................................................ 55

    Adonyi Rbert, Pannon Egyetem www.tankonyvtar.hu

  • 4 Adatstruktrk s algoritmusok

    www.tankonyvtar.hu Adonyi Rbert, Pannon Egyetem

    Grf szlessgi bejrsa .............................................................................................. 57 Krkeress....................................................................................................................... 58 Ersen sszefgg komponensek meghatrozsa........................................................... 59 Legrvidebb t keress.................................................................................................... 59

    Dijkstra-algoritmus...................................................................................................... 60 BellmanFord-algoritmus ........................................................................................... 63

    Feszt fa keress ............................................................................................................ 63 Kruskal-algoritmus...................................................................................................... 64 JarnikPrim-algoritmus............................................................................................... 65

    Hash tbla............................................................................................................................ 66 Hast fggvny .............................................................................................................. 66 Kulcs tkzs .................................................................................................................. 67

    STL fggvnyknyvtr ....................................................................................................... 67 STL adatszerkezetek ....................................................................................................... 69

    Lncolt lista az STL-ben ............................................................................................. 69 Az STL knyvtr vector adatszerkezete...................................................................... 70 Az STL knyvtr Queue adatszerkezete ..................................................................... 70 Az STL knyvtr Deque adatszerkezete ..................................................................... 71 Az STL verem adatszerkezete..................................................................................... 71 Verem implementlsa STL vector-al......................................................................... 71 Az STL knyvtr map adatszerkezete......................................................................... 72

    Algoritmusok az STL-ben............................................................................................... 73 Itertorok az STL knyvtrban ....................................................................................... 73

    Felhasznlt szakirodalom .................................................................................................... 75 Mellklet.............................................................................................................................. 76

    Lncolt lista megvalstsa C++ programozsi nyelven................................................. 76 Verem megvalstsa C++ programozsi nyelven tmb segtsgvel ............................ 77 Sor megvalstsa C++ nyelven tmb segtsgvel ........................................................ 78 Binris fa szlessgi bejrsa .......................................................................................... 80 Binris keres fa megvalstsa ...................................................................................... 82 Grf mlysgi s szlessgi bejrsa............................................................................... 83 Dijkstra algoritmusa ........................................................................................................ 85 Bellman-Ford algoritmusa szomszdsgi mtrixszal ...................................................... 85

  • Bevezets 5

    Bevezets A jegyzet clja, hogy Az adatstruktrk s algoritmusok trgy alapjait kpez ismeretanyagrl egy sszefoglal kpet adjon. Az adatstruktrk s algoritmusok elengedhetetlen alapjai a szoftvertervezs, szoftverfejleszts folyamatnak, komplex informatikai programoknak, szoftvereknek. A jegyzet sszekapcsolja a tmhoz kapcsold elmleti ismeretanyagot s a programozs jelleg trgyak teljestshez szksges gyakorlati jelleg tudst. A megfelel programozsi ismeretekhez elengedhetetlen, hogy tudjuk s ismerjk

    hogyan lehet az informcit a szmtgp memrijban trolni, milyen adatszerkezetekbe lehet az adatot szervezni, mik az elnyei s htrnyai a kivlasztott adatszerkezetnek, hogyan lehet algoritmusokat felpteni s az algoritmusokkal a trolt adatot mdostani, mik a kivlasztott adatszerkezeteknek s a hozzjuk kapcsold algoritmusok szmtsi

    ignye.

    Az alap adatszerkezetek s a hozzjuk kapcsold legfontosabb algoritmusok tulajdonsgainak s mkdsknek alapos ismeretben tudjuk csak az alkalmazs ignyeinek legmegfelelbb megoldst kivlasztani. A jegyzetben szerepl mintaprogramok s kdrszletek objektum orientlt szemlletben C++ programozsi nyelven kerlnek megvalstsra.

    Elfelttelek A jegyzet megrtshez felttelezzk, hogy az olvas ismeri a C++ programozsi nyelv alapjait, hogyan lehet egy C++ programot ltrehozni. Felttelezzk, hogy az olvas ismeri a C++ szintaktikai szablyait, milyen vltozkat lehet hasznlni, milyen paramter tadsi lehetsgeink vannak, hogy mkdnek a mutatk (pointer), hogyan lehet osztlyokat s objektumokat ltrehozni, milyen rkldsi szablyok vannak.

    Programozsi konvencik Egy j szoftverfejlesztsi krnyezet segti automatikus kdformzssal, sznekkel a programkd olvashatsgt. Azonban a krnyezet nyjtotta tmogats mellett rdemes nhny kdolsi konvencit betartani, hogy a programkd a ksbbiek sorn is rthet, rtelmezhet legyen.

    A javaslatok elsdleges clja az, hogy a programkd olvashat legyen, minsge javuljon. Javaslatok kzl nhny:

    adattpusok elnevezsre kis s nagybetket is hasznlhatunk, az els bet nagy legyen (pl. UserAccount)

    vltozk elnevezsre kis s nagybetket s hasznlhatunk, azonban az els bet kicsi legyen (pl. userAccount)

    Adonyi Rbert, Pannon Egyetem www.tankonyvtar.hu

  • 6 Adatstruktrk s algoritmusok

    konstansok elnevezsre nagybetket hasznljunk, ha tbb szt tartalmaz az elnevezs, akkor a szavak elvlasztsra az alhzs karaktert hasznljuk (pl. ACCOUNT_COUNT)

    fggvnyek, eljrsok elnevezse fejezze ki a cselekvst, hasznljunk igket, kis s nagybetket is tartalmazhatnak, azonban kis betvel kezddjenek (pl. getAccount())

    a nvterek (namespace) elnevezsre csak kisbetket hasznljunk (pl. model::geometry)

    sablon (template) elnevezsre egy nagy bett hasznljunk (pl. template ) ha egy nvnek rsze egy rvidts, akkor a rvidtst ne nagybetkkel hasznljuk (pl.

    importHtml()) a kd komplexitst cskkenthetjk, ha a vltoz neve megegyezik a tpusval (pl.

    Database database) hasznljuk a get/set/compute/find/initialize szavakat a megfelel funkci

    kifejezsre ciklusvltozknak hasznljuk az i, j, k, l vltozkat

    A fenti felsorols csak nhny kiragadott ajnls kdolsi konvencira. Tallhatunk ajnlst a forrsfjl felptsre, tagolsra, a vezrlsi szerkezetek szervezsre.

    Algoritmus s adat Az algoritmusok fontos rszei az informatiknak s mindennapi letnknek is. Nem csak a szmtstechnikban, hanem napi rutinjaink elvgzsben is algoritmusokat hajtunk vgre. Az algoritmus nem ms, mint jl meghatrozott lpsek sorozata egy bizonyos cl elrsnek a cljbl. Pldul, ha egy stemnyt stnk a receptben szerepl lpseket hajtjuk vgre, ebben az esetben a recept rja le az algoritmust.

    Tbbfajta lehetsgnk van algoritmus lersra. A legegyszerbb, ha egy beszlt nyelvet (magyar, angol) hasznlunk arra, hogy elmagyarzzuk hogyan mkdik az algoritmus. A szmtstechnikban azonban inkbb valamilyen matematikailag preczebb lerst kell vlasztanunk, pldul valamely programozsi nyelvet. A programozsi nyelvvel felptett algoritmust szmtgpnkn lefordthatjuk, futtathatjuk s vizsglhatjuk mkdst.

    Egy feladat megoldsra tbb, klnbz elven mkd algoritmust hozhatunk ltre. Az algoritmusokat sszehasonlthatjuk

    futsi id a bemenet fggvnyben a futs kzbeni memriahasznlat programkd mrete.

    Algoritmusok hatkonysgnak, komplexitsnak osztlyozsra a O (big o, ord) jellst hasznlhatjuk. A definci alapjn egy f(n) fggvny O(g(n)) halmazbeli, ha lteznek olyan c s N pozitv szmok, melyekre f(n)cg(n) brmely Nn szm esetn. Az O jells segtsgvel komplexitsuk alapjn jellemezni tudjuk az algoritmusokat, egy fels korltot tudunk mondani a futsi idre vonatkozan. A futsi idre vonatkoz fels korlt alapjn pldul egy O(n2)-beli algoritmus O(n3)-beli is.

    Egy algoritmus lehet determinisztikus. Az ilyen algoritmusnl brmilyen llapotban is tallhat egyrtelm, hogy mi lesz a kvetkez lps, amit vgrehajt. Az algoritmus vges, ha minden bemenetre a futsa vget r.

    www.tankonyvtar.hu Adonyi Rbert, Pannon Egyetem

  • Bevezets 7

    Az algoritmusok elemzse a szmtstudomny fontos rsze. Az algoritmusok a programozsi nyelv s a hardveres krnyezettl fggetlenl definilhatak, elemezhetek. A bonyolultsgelmlet az a terlet, ami ilyen szempontok alapjn foglalkozik egy algoritmussal.

    Szoftvertervezs s -fejleszts A hagyomnyos szoftverfejlesztsi folyamat az adat, vagy a folyamat orientlt megkzeltst hasznlja. Adat orientlt megkzelts esetn a szoftver tervezs sorn az informci brzolsn s az adatok bels sszefggseinek a feldertsn van a f hangsly. Az adatot hasznl, feldolgoz metdusoknak kevesebb szerepe van ez esetben. A folyamat orientlt tervezs sorn ellenttben a korbbival a szoftvertervezs elssorban a szoftver metdusok ltrehozsval foglalkozik, az adatnak itt kisebb szerep jut csak.

    Egy harmadik programozsi mdszertan, a manapsg mr igen szles krben ismert s bizonytottan hatkony objektum orientlt szemllet (object-oriented programming, OOP). Az objektum orientlt szoftverfejlesztsi folyamatban sokkal hatkonyabban lehet a bonyolult szoftverfejlesztsi krdseket kezelni, mint a korbbi adat-, vagy folyamat orientlt tervezsi mdszertanokban. Ez a hatkonysg abbl ered, hogy objektum orientlt megkzelts esetn az adat s a folyamat is hasonlan fontos szerepet kap, a kt rszterlet nincs fontossg szempontjbl megklnbztetve. Objektumok segtsgvel egyben kezeljk az sszetartoz adatokat s azokat a metdusokat, melyek ezeket az adatokat hasznljk. Az objektumok hierarchikus kapcsoldsainak feltrkpezse s megtervezsvel a szoftverfejleszts gyakorlatilag a val vilg kapcsoldsainak lemodellezst jelenti. Az objektum orientltsg f elnyei az absztrakci (abstraction) s az egysgbe zrs (encapsulation) s az osztlyok hierarchiba rendezsnek a lehetsge.

    Mieltt egy program megszletik, pontosan ismernnk kell azokat a tevkenysgeket, amiket el kell vgezni s implementlni kell ahhoz, hogy a program elvgezze a kitztt feladatokat. Az implementls eltt a program rszeket s azok kapcsolatait meg kell tervezni. Minl nagyobb, sszetettebb egy program, annl rszletesebb tervezsre van szksg. A tervezs sorn a vezrlsre s a felhasznlt programmodulokra vonatkozan klnbz dntseket hozunk.

    Objektum orientlt programozs Az ember a programozs s a vals vilg kezelse cljbl modelleket pt. Az objektum orientlt szoftverfejleszts kzben is a modellek ptse s a kapcsoldsok feltrkpezse a legfontosabb feladat.

    Objektum orientlt szoftverfejlesztsnl vannak olyan modellezsi alapelvek, melyek segtik a modell felptst. Az absztrakci elve alapjn a cl a vals vilg leegyszerstse olyan szintig, hogy csak a lnyegre, a modellezsi cl elrse rdekben szksges rszekre sszpontosthassunk. Ebben a rszben elhanyagoljuk azokat a rszeket, melyek nem fontosak, nem lnyegesek a cl szempontjbl. Ahogy a programozsi technika nevben is szerepel, a f hangsly az objektumokon van. Az objektum a modellezett vilg egy nll rszt, egysgt jelenti. Az objektum tartalmazza azokat a tulajdonsgokat s rtkeket, ami a modellben lerja az objektum viselkedst. Az objektumnak van egy bels llapota, struktrja s egy fellete amit a klvilg fel mutat.

    Az objektum orientlt szoftverfejleszts sorn az objektumokat nem egyesvel kezeljk (legalbbis a modell pts sorn), hanem kategorizlva, osztlyokknt tekintnk rjuk. Egy osztlyba a hasonl tulajdonsggal rendelkez objektumokat soroljuk. Az osztly tartalmazza azokat a tulajdonsgokat, melyek az objektum viselkedst, mkdst lerjk.

    Adonyi Rbert, Pannon Egyetem www.tankonyvtar.hu

  • 8 Adatstruktrk s algoritmusok

    Az OOP esetn az rkls egy olyan modellezsi eszkz, mely segtsgvel egy alap osztlybl j osztlyokat hozhatunk ltre (szrmaztatott osztly). Az rkls sorn az j osztly rendelkezhet az alap osztly bizonyos tulajdonsgaival. Vannak olyan osztlyok, melyekbl nem hozhat ltre objektum. Az ilyen osztlyt absztrakt osztlynak nevezzk, szerepe az rklsi hierarchiban az attribtumai s metdusai rklhetsgben van.

    Szoftvertechnolgia A szoftvertechnolgia (software engineering) a szoftver fejlesztse, zemeltetse s karbantartsval foglalkozik. A szoftvertechnolgia mrnki eljrsokat, ajnlsokat adhat a szoftverzemeltets s szoftverfejleszts kapcsn jelentkez krdsek kapcsn.

    Rgebben a szmtgpes programok egyszerek s kis mretek voltak. ltalban egyetlen programoz, vagy egy kis mret csapat t tudta ltni a feladatot. A hardvertechnolgia fejldsvel egyre nagyobb llegzet, komplexebb problmk vltak a szmtgp ltal megoldhatv. A komplex feladatok a sikeres teljests rdekben tervezst, elksztst, sszetett munkaszervezst ignyelnek. A mai vals feladatok, szoftverfejlesztsi projektek teljestse sorn a feladat mretei miatt nagy mret programozi csoportok dolgoznak a megoldsukon ltalban egymssal prhuzamosan. Egy ilyen projekt sorn a folyamatosan vltoz krnyezeti felttelek miatt szksges a jl elksztett, szervezett, sszehangolt, ellenrztt s dokumentlt munka. Az erre a clra alkalmazott mdszerekkel foglalkozik szoftvertechnolgia.

    Szoftvertechnolgit 1976-ban Boehm a kvetkezkppen definilta: Tudomnyos ismeretek gyakorlati alkalmazsa szmtgpes programok s a fejlesztskhz, hasznlatukhoz s karbantartsukhoz szksges dokumentcik tervezsben s ellltsban. Az IEEE mrnkket sszefog szervezet is definilta a szoftvertechnolgia fogalmt: Technolgiai s vezetsi alapelvek, amelyek lehetv teszik programok termkszer gyrtst s karbantartst a kltsg s hatrid korltok betartsval.

    Nehz egysgesen kezelni, sszefogni a klnbz szoftvertermkek fejlesztshez szksges szoftvertechnolgiai mdszereket. Sokfle szoftvertechnolgiai modell s eljrs szletett klnbz projektek kapcsn. A szoftvertechnolgia a kvetkez alaptevkenysgeket jelenti ltalban:

    1. A vevi /megrendeli elvrsok sszegyjtse, elemzse 2. A megolds vzlatnak, tervnek elksztse modell, absztrakci 3. Implementls, kd ellltsa 4. Telepts s tesztels 5. Karbantarts folyamatos fejleszts.

    Termszetesen vannak mg olyan tevkenysgek, amik kapcsoldnak, vagy beletartoznak az elbbi felsorolsba. Tbbek kztt ilyen tevkenysg lehet a projekt menedzsment, minsgbiztosts, vagy a termk tmogats.

    A szoftverfolyamat modellek a szoftver ellltsnak lpseire adnak eligaztst (milyen lpsekben kell ellltani a szoftvert az adott krnyezetben). Nem mondhatjuk hogy a kvetett modell az egyetlen megolds. Az elnyket s htrnyokat mrlegelve a vlaszthatjuk egyiket vagy msikat optimlis megoldsknt. Ezek a modellek kzl nhny fontosabb a kvetkez:

    1. Vzess modell 2. Evolcis modell 3. Boehm fle spirl modell 4. Gyors prototpus modell 5. Komponens alap (jrafelhasznls) 6. V modell 7. RUP (Rational Unified Process)

    www.tankonyvtar.hu Adonyi Rbert, Pannon Egyetem

  • Bevezets 9

    A szmtgppel tmogatott szoftvertervezs (Computer-Aided Software Engineering - CASE) hasznlt szoftvereket nevezzk CASE-eszkzknek. CASE eszkzk a kvetkez lpseket tmogatjk:

    Kvetelmnyspecifikci: grafikus rendszermodellek, zleti s domain modellek Elemzs/tervezs: adatsztr kezelse, felhasznli interfsz generlst egy grafikus

    interfszlersbl, a terv ellentmonds mentessg vizsglata Implementci sorn: automatikus kdgenerls, verzikezels Szoftvervalidci sorn: automatikus teszt-eset generls, teszt-kirtkels Szoftverevolci sorn: forrskd visszafejts (reverse engineering); rgebbi verzij,

    programnyelvek automatikus jrafordtsa jabb verziba.

    Mindegyik lpsnek rsze az automatikus dokumentumgenerls s a projektmenedzsment tmogats.

    UML Az UML (Unified Modeling Language) egy egysges modellez nyelv (http://www.uml.org), amit az Object Management Group hozott ltre. Az UML egy olyan eszkztr, amelynek segtsgvel jl rthet/kezelhet a szoftverrel szemben tmasztott kvetelmnyek, a szoftver felptse s a szoftver mkdse. Az UML grafikus elemeket tartalmaz, mellyel tmogatja a szoftver fejleszts fzisait. Az UML manapsg elfogadott s tmogatott ler eszkz, hiszen szmos szoftver nyjt lehetsget az UML hasznlathoz.

    Az UML diagramokat hasznl a modell elemek lersra. Ezek kt f csoportba sorolhatk: statikus s dinamikus diagramok. A statikus diagramok a szerkezett, a dinamikusak a viselkedst modellezik a rendszernek.

    Osztlydiagram: az lland elemeket, azok szerkezett s egyms kztti logikai kapcsolatt jelenti meg.

    Objektumdiagram: az osztlydiagrambl szrmaz rendszer adott pillanatban val llapott jelenti meg.

    Csomagdiagram: a csomagok ms modellelemek csoportostsra szolglnak, ez a diagram a kztk lev kapcsolatokat brzolja.

    sszetev diagram: a diagram implementcis krdsek eldntst segti. A megvalstsnak s a rendszeren belli elemek egyttmkdsnek megfelelen mutatja be a rendszert.

    sszetett szerkezeti diagram: modellelemek bels szerkezett mutatja. Kialakts diagram: futsidej felptst mutatja. Tartalmazza a hardver s a

    szoftverelemeket is. Tevkenysgdiagram: A rendszeren belli tevkenysgek folyamatt jelenti meg. Hasznlati eset diagram: A rendszer viselkedst rja le, gy, ahogy az egy kls

    szemll szemszgbl ltszik. llapotautomata diagram: objektumok llapott s az llapotok kztti tmeneteket

    mutatja Kommunikcis diagram: objektumok hogyan mkdnek egytt a feladat

    megoldsa sorn, hogyan hatnak egymsra. Sorrenddiagram: zenetvlts idbeli sorrendjt mutatja. Idzts diagram: klcsnhatsban ll elemek llapotvltozsait vagy

    llapotinformciit rja le.

    Adonyi Rbert, Pannon Egyetem www.tankonyvtar.hu

  • 10 Adatstruktrk s algoritmusok

    www.tankonyvtar.hu Adonyi Rbert, Pannon Egyetem

    C++ programozsi nyelv A C programozsi nyelvet Dennis Ritchie az 1970-es vek elejn fejlesztette ki (Ken Thompson segtsgvel) a UNIX opercis rendszereken val hasznlat cljbl. Ma mr jformn minden opercis rendszerben megtallhat, s a legnpszerbb ltalnos cl programozsi nyelvek egyike, rendszerprogramozshoz s felhasznli program ksztshez egyarnt jl hasznlhat. Az oktatsban s a szmtgpes tudomnyokban is jelents szerepe van.

    A C++ egy ltalnos cl, magas szint programozsi nyelv. Tmogatja a procedurlis-, az objektumorientlt- s a generikus programozst, valamint az adatabsztrakcit. Napjainkban szinte minden opercis rendszer al ltezik C++ fordt. A nyelv a C hatkonysgnak megrzse mellett trekszik a knnyebben megrhat, karbantarthat s jrahasznosthat kd ltrehozsra. Ez azonban sok kompromisszummal jr, amire utal, hogy ltalnosan elterjedt a mid-level minstse is, br szigor rtelemben vve egyrtelmen magas szint (wikipedia.hu).

    Ebben a rszben a teljessg ignye nlkl a C++ programozsi nyelv nhny jellemzjt soroljuk fel. A jegyzetnek nem clja a C s C++ nyelvek alapos bemutatsa. Az adatstruktrk s algoritmusok jegyzet hasznlathoz ismerni kell

    az elemi adattpusokat, struktrkat, unit, osztlyok alapjn ltrehozhat sszetett adatszerkezeteket, a vezrlsi szerkezeteket,

    osztlyok, konstruktor, destruktor, msol konstruktor, dinamikus memriakezels, memria foglals felszabadts, mutatk hasznlata, referencia

    tpus, tmbk s mutatk kapcsolata, fggvnyek, paramter-tads mkdse, fggvnyek tdefinilsa (overloading) konstansok s makrk sablonok.

  • Dinamikus tmb s lncolt lista 11

    Dinamikus tmb s lncolt lista A kvetkez fejezetekben az elemi adatstruktrkat mutatjuk be, gy mint a verem, sor, hast tbla. Ezekben az adatstruktrkban az adat valamilyen alapelvek alapjn kerl trolsra. Az adat trolshoz ltalban dinamikus tmbt, vagy lncolt listt hasznlhatunk. A fejezet els rszben ezrt a C++ programozsi nyelv tmbkezelsi lehetsgeinek rvid ismertetse, majd a lncolt listk bemutatsa kvetkezik.

    Mieltt egy adatstruktrt ltrehozunk, el kell dntennk, hogy dinamikus tmbt, vagy lncolt listt szeretnnk az adatok trolshoz hasznlni. Emiatt a tmbt s a lncolt listt hvhatjuk alap adatstruktrnak is. A ksbbiekben bemutatand absztrakt adat struktrk (verem, sor, fa, grf) a tmbt, s/vagy a lncolt listt hasznljk. Lehetsgnk van egy verem ltrehozsra tmb s lncolt lista segtsgvel is. Persze az alap adatstruktra kivlasztsa befolysolhatja az absztrakt adatstruktra hasznlhatsgt s hatkonysgt.

    Tmb s dinamikus tmb A tmb a legegyszerbb s legelterjedtebb eszkz sszetartoz adatok egyttes kezelsre. A C++ nyelvben a tmbk s a mutatk sszekapcsoldnak. Tmbk elrhetek mutatkon keresztl, mutatk segtsgvel memriaterletet tudunk a mutathoz rendelni s ezek utn tmbknt kezelni.

    A C++ nyelvben az N mret tmbt 0 s N-1 egszekkel indexelhetjk. A tmb mrete statikus, fordtsi idben jn ltre, hacsak nem dinamikusan a programoz gondoskodik a tmbterlet lefoglalsrl majd felszabadtsrl.

    A dinamikus memriahasznlat sorn, hogy adataink szmra csak akkor foglalunk memriaterletet, amikor szksg van r, ha pedig feleslegess vlik a lefoglalt memriaterlet, akkor azonnal felszabadtjuk azt. Ez azrt fontos a C s C++ programozsi nyelvekben, mivel itt nincs olyan szemtgyjt (garbage collector) mint a JAVA -ban vagy C# -ban. A felszabadtatlan memria memriaszivrgshoz (memory leak) vezet.

    A C++ -ban lehetsg van hasznlni a C malloc s free utastst, memria terlet foglalsra s felszabadtsra, azonban hasznlhatjuk az erre ltrehozott C++-os opertorokat is. A new opertor az operandusban megadott tpusnak megfelel mret terletet foglal a memriban, s egy arra mutat pointert ad vissza. A delete felszabadtja a new ltal lefoglalt memriaterletet:

    Egy mutat lefoglalsa s felszabadtsa a kvetkez kdsorokkal vgezhet el C++ programozsi nyelven:

    int *p = new int;

    delete p;

    Tbb egyms utn elhelyezked elem szmra is foglalhatunk terletet. Ezt az adatstruktrt nevezzk dinamikus tmbnek. A dinamikus tmb lefoglalshoz s felszabadtshoz a kvetkez kdsorokat kell vgrehajtani:

    int *v = new int [123];

    delete[] v;

    Adonyi Rbert, Pannon Egyetem www.tankonyvtar.hu

  • 12 Adatstruktrk s algoritmusok

    Tbbdimenzis tmbt dinamikus lefoglalsa esetn a dimenzik szmnak megfelelen lpsenknt le kell foglalni a mutatkat. A kvetkez pldban kt dimenzis mtrixot foglalunk s szabadtunk fel mutatk segtsgvel:

    int **T = new int * [17];

    for(int i = 0;i < 17;i++) {

    T[i] = new int [10];

    for(int j = 0;j < 10;j++) {

    T[i][j] = ERTEK;

    }

    }

    for(int i = 0;i < 17;i++){

    delete[] T[i];

    }

    delete[] T;

    Lncolt lista A tmbk segtsgvel sok esetben meg lehet oldani az sszetartoz adatok trolst, azonban megvannak ennek az adatstruktrnak is a htrnyai:

    a tmb mrett elre ismernnk kell (kivtel dinamikus tmbk) a mr lefoglalt, ltrehozott tmb mrete nem mdosthat a memriban folytonosan kerl trolsra, ha egy j elemet szeretnnk a tmbbe beszrni, a

    tmb egyik felben szerepl elemek mozgatshoz vezet. Ezeket a htrnyokat a lncolt lista adatszerkezettel elkerlhetjk. Lncolt lista

    segtsgvel lefoglalt tmb mrete miatti korltokat elkerlhetjk, a lista hosszra csak a rendelkezsre ll szabad memria mennyisge ad korltot. A lncolt lista egy eleme kt rszbl pl fel. Egyrszt tartalmazza a trolni kvnt adatot, vagy adatokat s tartalmaz egy olyan mutatt, ami a lista egy msik elemt mutatja. A lncolt lista a dinamikus tmbhz kpesti htrnya a kzbls elemek elrhetsgbl ered. Mg egy tmb esetn ha tudjuk, hogy a k. elemet szeretnnk elrni, akkor a tmb indexelsvel rgtn hozzfrhetnk ehhez az adathoz, addig a lncolt listban a lista elejrl indulva a mutatkon keresztl addig kell lpkedni, mg a k. elemhez nem rtnk. A vletlenszer lista elem megtallsa a lista hosszval arnyos idt ignyel.

    Lncolt listkat gyakran alkalmazzuk sszetettebb adatstruktrk (verem vagy sor) ptsekor. A lncolt lista adatmezi tetszleges adatot trolhatnak, akr mutatkat ms adatszerkezetekre, vagy tbb rszadatbl felpl struktrkat. Tbb mutat hasznlatval nemcsak lineris adatszerkezeteket tudunk pteni, hanem tetszleges elgaz struktrt is. Egyszeresen lncolt lista Egyszeresen lncolt listban egy darab mutat jelli a lista rkvetkez elemt. Ha ismerjk a lista legels elemt (lista feje), akkor abbl elindulva a mutatk segtsgvel vgigjrhatjuk a listban trolt elemeket. A lista legutols elemnek mutatjnak rtke NULL, ez jelzi, hogy tovbb nem tudunk haladni a listban. Lncolt lista esetn ltalban egyszeresen lncolt listra gondolunk.

    Egy egsz szmokat trol lncolt listt pldul a kvetkez osztllyal valsthatjuk meg: class IntNode{

    www.tankonyvtar.hu Adonyi Rbert, Pannon Egyetem

  • Dinamikus tmb s lncolt lista 13

    public:

    IntNode() {

    next = 0;

    }

    IntNode(int i, IntNode *new_node = 0) {

    data = i; next = new_node;

    }

    int data;

    IntNode *next;

    };

    Minden egyes lista elem (IntNode) a data tagban trolja az adatot, a next mutatja a lista kvetkez elemt. Az IntNode osztly kt konstruktort is tartalmaz. Az els NULL rtkre lltja a next mutatt s az adat tag rtkt nem definilja; a msodik kt paramtert hasznl, az els paramterrel a data adattagot, a msodikkal a next mutat rtkt inicializlja.

    Az IntNode osztly segtsgvel hozzunk ltre egy hrom elemet tartalmaz lncolt listt:

    IntNode *p = new IntNode(43);

    p->next = new IntNode(21);

    p->next->next = new IntNode(101);

    A 43, 21 s 101-et tartalmaz lncolt lista az 1. brn lthat. A p mutat jelli a lista els elemt (fejt, head).

    1. bra: Lncolt lista hrom elemmel

    Ily mdon a lncolt listt akrmeddig bvthetjk (ameddig tudunk j elemet foglalni a memriban). Azonban ez a mdszer a lista bvtsre egy bizonyos hossz utn nehzsgekhez vezet, hiszen pldul egy 100 elem lista utols elemnek a ltrehozshoz 99 hosszsgban kellene a next-eket egyms utn felfznnk, majd vgigjrni. Ezt a kellemetlensget elkerlhetjk, ha nemcsak a lista els elemt, hanem az utolst is szmon tartjuk (tail). Ehhez az jfajta listhoz hozzunk ltre egy IntList nev osztlyt, ami magt a listt kezeli.

    class IntList {

    public:

    IntList() {head = tail = 0;}

    ~IntList();

    bool isEmpty() {return head == 0;}

    Adonyi Rbert, Pannon Egyetem www.tankonyvtar.hu

  • 14 Adatstruktrk s algoritmusok

    void addToHead(int);

    void addToTail(int);

    private:

    IntNode *head, *tail;

    };

    Az IntList osztly kt adattagot tartalmaz, kt mutatt, melyek a lista els s a lista utols elemeire mutatnak (head, tail). A lista osztly tartalmaz kt olyan metdust, mellyel a lista elejre (addToHead) vagy a vgre (addToTail) tudunk j elemet beszrni. A lncolt lista a kvetkez utastssal hozhat ltre:

    IntList L;

    Beszrs lncolt listba Ha van egy lncolt listnk valsznleg a lista bvtse az egyik legfontosabb feladat, amit vgre kell hajtanunk. A lista bvts lpsei kis mrtkben klnbznek egymstl attl fggen, hogy a lista melyik pozcijba szeretnnk az j lista elemet beszrni. Ha a lncolt lista aktulis legels eleme el szeretnnk beszrni egy j elemet, akkor a kvetkez lpseket kell vgrehajtani: 1. Egy j cscs ltrehozsa/lefoglalsa 2. rtkads az j lista cscs adat tagjnak 3. Mivel a lista els eleme lesz az j cscs, ezrt az j cscs next tagjnak rtke a lista korbbi

    els cscsnak cme lesz, ami a head mutat aktulis rtkvel egyenl 4. A head-nek a lista j cscsra kell mutatnia, hogy a ksbbiekben is elrjk a lista els elemt.

    2. bra: Az elz lncolt lista els helyre j elem beszrsa

    A 2. brn az elz lista els pozcijba lncoltuk be a 80-as listaelemet. Az brn a szaggatott vonallal brzolt nyl jelzi azt a mutatt, amit a beszrs sorn megvltoztatunk. Az els helyre beszrst a kvetkez osztly-metdussal vgezhetjk el:

    void IntList::addToHead(int new_data) {

    head = new IntNode(new_data, head);

    if(tail == 0)

    tail = head;

    }

    A beszrs mveletre az IntNode osztly konstruktort hvtuk segtsgl, mely az j memriaterlet lefoglalsa utn a korbbi head mutat rtkre irnytja az jonnan lefoglalt

    www.tankonyvtar.hu Adonyi Rbert, Pannon Egyetem

  • Dinamikus tmb s lncolt lista 15

    IntNode objektum next mutatjt. Abban az esetben, ha lncolt lista mg nem tartalmazott egyetlen egy elemet se korbban, gondoskodni kell hogy a tail mutat is helyes lista elemre mutasson a mvelet vgrehajtsa utn (tail = head).

    Lncolt lista utols helyre val beszrs els kt lpse nem vltozik az els helyre val beszrshoz kpest, ugyangy le kell foglalni a megfelel memriaterletet az j elem szmra, majd inicializlni kell az adatrszt. Az utols helyre val beszrs lpsei a kvetkezek: 1. Egy j cscs ltrehozsa/lefoglalsa 2. rtkads az j lista cscs adat tagjnak 3. Mivel az j cscs lesz a lista utols eleme, ezrt az j cscs next-jnek rtke NULL 4. Az j cscsot a korbbi utols cscs next-jnek az j cscsra val lltsval befzzk a listba

    (ez a cscs a tail aktulis rtke) 5. A tail-nek a lista j cscsra kell mutatnia.

    Az utols helyre beszrst a kvetkez osztly-metdussal vgezhetjk el: void IntList::addToTail(int new_data) {

    if(tail != 0) {

    tail->next = new IntNode(new_data);

    tail = tail->next;

    } else

    head = tail = new IntNode(new_data);

    }

    Ha a lista mr tartalmaz legalbb egy elemet, akkor a tail mutat utn kell befzni az j lista elemet, majd frissteni kell a tail mutat rtkt (tail = tail->next). Ha mg res volt a lista, akkor a lista vgre val beszrs gyakorlatilag megegyezik a lista elejre val beszrssal, hasznlhatnnk akr az addToHead metdust is a mvelet vgrehajtsra.

    Lthatjuk, hogy a beszrs mvelet head s tail mutatkat tartalmaz egyszeresen lncolt lista esetn konstans idben (O(1)) elvgezhet. Ugyanakkor, ha nem hasznlnnk tail mutatt az utols elem jellsre, akkor a lista elejre val beszrs konstans idt ignyel, de ha a lista utols helyre akarjuk beszrni az j lista tagot, akkor vgig kell menni az egsz listn, hogy megtalljuk az utols lista elemet. Ebben az esetben a lista hosszval arnyos a beszrs idignye (O(n)). Trls lncolt listbl Hasonlan a beszrs mvelethez, a trls esetn is klnbz lpseket kell a trlend lista elem helynek fggvnyben. Akkor vagyunk egyszerbb helyzetben, ha az els lista elemet s a listban trolt adattagot akarjuk trlni az egyszeresen lncolt listbl. A trls vgrehajtshoz a kvetkez lpseket hajtsuk vgre: 1. lltsunk egy ideiglenes mutatt a lista els elemre 2. lltsuk a head mutatt a jelenlegi lncolt lista msodik elemre (pl. az ideiglenes mutat next-

    je segtsgvel megkaphatjuk a msodik listaelemet) 3. Az ideiglenes mutat memriaterlett felszabadthatjuk.

    ltalban a fenti lpsek vgrehajtsval elvgezhetjk az els elem trlst, azonban vizsgljunk meg kt specilis esetet. Ha a lista res, akkor trlni sem tudunk belle, ezrt ezt az esetet kln kell kezelni. A msik specilis eset, amikor egy egy elem listbl trlnk, mert ekkor a trls utn egy res listt kapunk, teht a head s a tail mutatt is NULL-ra kell lltani.

    Adonyi Rbert, Pannon Egyetem www.tankonyvtar.hu

  • 16 Adatstruktrk s algoritmusok

    A lista utols elemnek a trlshez meg kell keresni az utols eltti elemet (egyszeresen lncolt lista esetn), mert ennek az elemnek a next mutatjt kell aktualizlnunk a trls utn. Az utols eltti elem egy ciklussal kereshet meg, a megllsi felttel gyes belltsval (tmp->next!=tail). A ciklusban a tmp mutatt lptetjk a head-bl indulva egszen addig, mg a next mutatja az utols elemre nem mutat, azaz a tmp az utols eltti listaelemre mutat. Ha van utols eltti elem, akkor annak megtallsa teht:

    for(tmp=head;tmp->next!=tail;tmp=tmp->next)

    Ha mr megtalltuk az utols eltti lista elemet, akkor az utols listaelem trlse hasonl lpseket tartalmaz, mint amiket az els elem trlsekor elvgeztnk. Az elvgzend mveletek a kvetkezek: 1. Keressk meg a lista utols eltte elemt (tmp mutat segtsgvel) 2. A tmp mutat next-je legyen NULL mutat 3. A tail mutathoz tartoz memriaterletet szabadtsuk fel 4. lltsuk a tail mutatt a tmp ltal jellt memriaterletre.

    Hasonlan a lista elejrl val trls esethez itt is kt specilis esetre kell odafigyelni. Ha a lista res, akkor az utols elem trlst sem tudjuk elvgezni. Ha a lista egy elemet tartalmaz, akkor az utols elem eltvoltsval egy res listt kapunk.

    ltalnos esetben nem a lista elejrl, vagy a vgrl trlnk, hanem a lista brmely pozcijban tallhat elemet trlhetjk. ltalban egy adott rtket kell megtallnunk a listban, majd eltvoltani azt belle. Az eltvolts azt jelenti, hogy a trlend elem eltti listaelem next mutatjt tlltjuk az eltvoltand listaelem utni elemre, majd elvgezzk a trlst. Ahhoz, hogy a keresett elemet ki tudjuk lncolni a listbl, rdemes a keress sorn az aktulis elem eltti listaelemet is megjegyezni.

    A 3. brn egy pldt lthatunk lncolt listban val keress majd a keresett elem trlsre. Tegyk fel, hogy a 21-et tartalmaz elemet szeretnnk megtallni, majd trlni a listbl. Ehhez a tmp s a pred segdmutatkat hasznljuk. A tmp az ppen aktulisan megtallt listaelemre mutat, a pred pedig az aktulis eltti elemre. A tmp s a pred mutatkat addig lptetjk, mg megtalljuk a keresett rtket tartalmaz elemet. Az rtk megtallsa utn a pred-hez tartoz listaelem kvetkez elemnek belltjuk a tmp kvetkez listaelemt. Ezek utn trlhetjk a tmp ltal mutatott listaelemet. Az egyszeresen lncolt lista C++ implementcija kiegsztve a lncolt listbl val trls mveletekkel a mellkletben tallhat.

    www.tankonyvtar.hu Adonyi Rbert, Pannon Egyetem

  • Dinamikus tmb s lncolt lista 17

    3. bra: Keress s trls egyszeresen lncolt listban

    Ktszeresen lncolt lista Az egyszeresen lncolt lista egy listaeleme csak egy mutatt tartalmaz, ami a lista kvetkez elemnek cmt jelli, gy kzvetlenl nem lehet megmondani hogy mi volt az elz elem. Mr az eddigiek alapjn is lthattuk, hogy van olyan lista mvelet (pl. lista vgrl val trls), amikor az elz listaelem mutatjt kell mdostani. Ha a listaelem az elz s a kvetkez elemre is tartalmazna egy-egy mutatt, akkor ezzel bizonyos lncolt lista mveletek egyszersdnek, ugyanakkor a kt mutat miatt termszetesen vannak olyan mveletek is, melyek emiatt bonyolultabbak lesznek. Az ilyen listkat ktszeresen lncolt listnak (doubly linked list) nevezzk. A 4. brn egy ktszeresen lncolt listt lthatunk, melyben a 43, 21 s 101 rtkeket troltuk.

    4. bra: Hrom elemet tartalmaz ktszeresen lncolt lista

    A ktszeresen lncolt lista implementlsa hasonlan trtnhet, mint az egyszeresen lncolt vltozat. A lista adattagoknl egy elre mutat (next) s egy htra mutat (prev) pointert is ltre

    Adonyi Rbert, Pannon Egyetem www.tankonyvtar.hu

  • 18 Adatstruktrk s algoritmusok

    www.tankonyvtar.hu Adonyi Rbert, Pannon Egyetem

    kell hoznunk s j elem beillesztsekor gondoskodni kell, hogy mind az elre, mind a htrafel mutatk megfelelen vltozzanak. A kvetkez kdrszletben egy ktszeresen lncolt lista implementcijt lthatjuk.

    class IntDNode{

    public:

    IntDNode() {

    next = prev = 0;

    }

    ...

    int data;

    IntDNode *next;

    IntDNode *prev;

    }

    Krkrsen lncolt lista Bizonyos esetekben krkrsen lncolt listt (circular list) kell megvalstanunk. Ebben a listban a listaelemek egy krt alkotnak, az els s az utols elem ssze van ktve egymssal. A kr miatt minden elemnek van egy r kvetkezje. Ilyen pldt tallhatunk a processzor temezsekor, amikor minden folyamat ugyanazt az erforrst hasznlja, az temez azonban nem futtat egy folyamatot egszen addig mg minden eltte lev nem kerlt kapott processzoridt. Egy ilyen listban, aminek nincs kitntetett els, vagy utols eleme, elg brmely elemt ismernnk, hogy ezutn az elemen keresztl hozzfrjnk az sszes tbbihez, mindssze arra kell figyelni a lncolt lista vgigjrsakor, hogy melyik volt az az elem, ahonnt a bejrst indtottuk.

    rszemes lista A lista mveletek (pl. trls) egyszersdne, amennyiben a lista vgein lev elemeknl nem kellene ellenrzseket tennnk. Ezt megvalsthatjuk gy hogy specilis listaelemeket (rszemeket) vezetnk be a lista hatrainak jellsre. Ezek az rszemek ugyanolyan felptsek, mint a lista brmely eleme, fizikailag a lncolt listban szerepelnek, azonban logikailag nem rszei a listnak. rszemek segtsgvel a null mutatk kezelsbl ered ellenrzseket elkerlhetjk. Ritka mtrix trolsa lncolt listval Sokszor tblzatos formban, tbbdimenzis tmbben trolunk mtrixokat. Azonban ha a mtrix kevs rtket tartalmaz memriahasznlat szempontjbl gazdasgtalan a tmb hasznlata. Az ilyen mtrixokat ritka mtrixnak hvjuk (sparse matrix).

    Nagymret mtrix trolsra a sorok s oszlopok szmnak szorzata hatrozza meg a trolshoz szksges tmb mrett. Akkor, ha ennl a szorzatnl lnyegesen kisebb azoknak a cellknak a szma, ahol adatot trolunk, akkor rdemesebb egy lncolt listt hasznlni tmb helyett. A lncolt listban trolni kell a cella rtkt s az rtkhez tartoz indexeket. A lncolt lista segtsgvel lnyegesen cskkenthetjk a mtrix trolsra szksges memriahasznlatot.

  • Verem adatszerkezet 19

    Verem adatszerkezet A verem (stack) egy olyan lineris adatstruktra, melybe csak az egyik vgn lehet adatot berakni, vagy adatot kivenni belle. Verem jelleg trolsi struktrval nem csak a szmtstechnikban tallkozhatunk, hanem mindennapokban is sok esetben verem jelleggel vgznk mveleteket (pl. tkezszekrnyben tnyrokat egymsra rakva troljuk, a legfelst tudjuk csak kivenni s a legtetejre tudunk j tnyrt berakni). A verem amiatt, hogy az utoljra berakott elemet lehet belle elszr kivenni egy LIFO (last in first out) jelleg adatszerkezet. Verem adatszerkezetet a szmtstechnikban sok helyen hasznljuk: opercis rendszerek, fggvnyek hvsnl egy verem terletre kerl a hv fggvny paramter listja, loklis vltozi s visszatrsi cme.

    Ahhoz, hogy a verem adatszerkezetet hasznlni tudjuk definilni kell nhny mveletet, amit rtelmezni tudunk verem esetn. A verem hasznlathoz s llapotainak lekrdezshez a kvetkez mveletekre van szksgnk: Clear() verem rtse isEmpty() leellenrzi, hogy res-e a verem Push(i) az i elemet a verem tetejre teszi Pop() kiveszi a legfels elemet a verembl s visszatr annak rtkvel

    A kvetkez pldban push s pop mveletek egy sorozatt hajtjuk vgre, a verem aktulis tartalmt a 5. brn lthatjuk. A verembe elszr berakjuk a 7, majd a 11 szmokat. A verem tetejn lev szm eltvoltsa utn berakjuk az 51-et. Amivel vgeredmnyben a verem a 7 s 51 elemeket tartalmazza.

    5. bra: A verem tartalmnak vltozsa push s pop mveletek hatsra

    A verem nagyon hasznos adatszerkezet, ltalban akkor van r szksgnk, ha a trolshoz kpest fordtott sorrendben van szksg az adatokra. Verem alkalmazsra egy mintafeladat lehet egy matematikai kifejezsben a zrjelek nyit s zr felnek a prostsa. A zrjel prosts feladat knnyen megoldhat egy verem segtsgvel. A kifejezs balrl jobbra val olvassval nyit zrjel esetn a zrjelet a verem tetejre tesszk (Push), bezr zrjel esetn pedig kiolvasunk (pop) egy elemet a verem tetejrl. A kiolvasott zrjelnek ugyanolyan fajtjnak kell lennie, mint a bezr volt. A kifejezs hibs, ha a kivett zrjel nem ugyanolyan fajtj, vagy res verembl prblunk meg kiolvasni, vagy ha az ellenrzs vgn a veremben maradt valami.

    Ha egy res verembl akarunk valamit kivenni a verem tetejrl (pop), akkor ltalban az res verem hiba szokott jelentkezni. A veremben trolhat elemek szmra ltalban egy fels korltot szoks adni, ha tbb elemet tesznk a verembe, mint ez a fels korlt, akkor a tele verem hibazenetet kapjuk (stack overflow).

    Verem implementlsa tmbbel A kvetkez pldaprogramban egy egszek trolsra alkalmas vermet hozunk ltre. A verem dinamikus tmbt hasznl az elemek trolsra. A verem maximlis mrett/elemszmt a ltrehozskor hatrozzuk meg.

    Adonyi Rbert, Pannon Egyetem www.tankonyvtar.hu

  • 20 Adatstruktrk s algoritmusok

    class IntStack {

    public:

    IntStack(int cap) {

    top = 0; capacity = cap;

    data = new int[capacity];

    }

    ~IntStack() {

    delete [] data;

    }

    bool isEmpty() const {return top==0;}

    void Push(int i);

    int Pop();

    void Clear();

    private:

    int *data;

    int capacity;

    int top;

    }

    Az IntStack osztly a data dinamikus tmbben trolja a benne szerepl elemeket. A dinamikus tmbt a konstruktor hozza ltre, a destruktor szabadtja fel. A verem a dinamikus tmbbel kapcsolatban tudja, hogy sszesen mennyi elem fr bele (capacity) s jelenleg mennyi elem van benne, azaz hogy hnyadik indexig tartalmaz a tmb trolt rtkeket (top). Az isEmpty() metdussal azt lehet lekrdezni, hogy a verem tartalmaz-e mr valamit.

    A Pop() metdus a verem tetejn lev elemmel tr vissza, mikzben a verem tetejrl lekerl ez a visszaadott rtk. Fizikailag benne maradhat a tmbben a visszaadott rtk, azaz nem kell a tmb rtkt mdostani, hiszen elg ha a top vltoz mdostsval tudjuk, hogy a veremnek mr nem rsze a legutbb visszaadott elem. A Pop() metdus a kvetkezkppen plhet fel:

    int IntStack::Pop() {

    if(top > 0) {

    top--;

    return data[top];

    } else {

    cout

  • Verem adatszerkezet 21

    A Push() metdus a paramterknt kapott j rtket helyezi el a verem tetejre. Abban az esetben, ha a verembe mg elfr (top

  • 22 Adatstruktrk s algoritmusok

    www.tankonyvtar.hu Adonyi Rbert, Pannon Egyetem

    void IntStack::Push(int i) {

    data.addToTail(i);

    }

    int Pop() {

    if(data.isEmpty())

    //hibauzenet

    else return data.deleteFromTail();

    }

    Az IntStack osztlyban a korbban bevezetett IntList egszeket tartalmaz lncolt listt hasznljuk. A lncolt listba a vgre pakoljuk be az j rtkeket (addToTail()) s csak a vgrl vehetnk ki belle (deleteFromTail()). Ezzel biztostjuk a LIFO elvet.

    Lncolt lista hasznlata esetn az a hiba nem fordulhat el, hogy a verem megtelik, hiszen a lista csak akkor bvl pontosan egy elemmel, ha j elemet tesznk bele. A verembl kivtelkor a listbl is rgtn trldik s felszabadul a kivett elem. res verem esetn a lncolt lista sem tartalmaz elemet, ezrt az res verembl/listbl val elem kivtelt kezelni kell.

  • Sor adatszerkezet 23

    Sor adatszerkezet A sor (queue) nem ms, mint egy vrakozsi lista, ami gy nvekszik, hogy elemeket tudunk a vgre hozzadni s gy cskkenhet, hogy elemeket vehetnk el az elejrl. A veremmel ellenttben a sor olyan adatszerkezet, melynek mindkt vgn vgezhetnk mveleteket. A sor jellegbl addan az utoljra hozzadott elemnek egszen addig vrakoznia kell, mg a korbban hozzadott elemeket ki nem vettk belle. Az ilyen adatszerkezetek FIFO (first in first out) tulajdonsgak.

    A sorhoz a kvetkez alapmveleteket definilhatjuk: clear() - sor rtse isEmpty() - annak ellenrzse, hogy a sor res-e enqueue(element) az j elem a sor vgre val beszrsa dequeue() - visszaadja a sor elejn lev elemet.

    A 6. bra az enqueue s dequeue mveletek hatst szemllteti egy egszeket tartalmaz soron. res sorbl indulva berakjuk a sorba a 3, 13, majd az 1 rtkeket. Ezutn a sorban a 13 s az 1 rtk maradt.

    6. bra: Az enqueue s dequeue mveletek hatsa egy sor adatszerkezeten

    sszehasonltva a sort a veremmel lthatjuk, hogy ebben az adatszerkezetben a veremmel ellenttben az adatszerkezet mindkt oldaln trtnnek adat mveletek. Ugyangy, mint a veremnl itt is lehetsgnk van a sorban trolt adatok trolsra dinamikus tmbt, vagy lncolt listt hasznlni.

    Ha a sor adatszerkezetben troland adatokhoz dinamikus tmbt szeretnnk hasznlni, akkor a tmbhz nyilvn kell tartani a sor elejt s vgt, azaz az els elem s az utols elem indext is. Ha a kisebb index jelli a sor elejt, a nagyobb (vagy nagyobb egyenl) pedig a sor vgt, akkor mind a sorbl kivtel, mind a sorba beraks esetn valamely tmbindex nvekedse trtnik. Ha valamely index a tmb utols elemre mutat, akkor az index nvekedse esetn a r kvetkez rtk a tmb legels eleme lesz. res sor esetn a sor eleje s a vge indexek egy soron kvli rtkre mutatnak. Teli sor esetn a sor vge index a sor elejtl balra mutat rtket jelli, ekkor a sor vge index nem nvelhet (a sor vge index balrl nem elzheti le a sor eleje indexet). A sor adatszerkezet egy gynevezett krkrs tmb segtsgvel implementlhat. A 7. brn egy sor adatstruktrt lthatunk egy nyolc mret dinamikus tmbt hasznlva. A sor kezdetben a 13, 1, 2 s 7 egszeket tartalmazza. Els lpsben berakjuk a sor vgre a 30 rtket, majd a kvetkez lpsben kivesszk a sor elejn tallhat elemet.

    Adonyi Rbert, Pannon Egyetem www.tankonyvtar.hu

  • 24 Adatstruktrk s algoritmusok

    7. bra: Sor megvalstsa krkrs dinamikus tmb segtsgvel

    A kvetkez pldban C++ nyelven implementlunk egy olyan sort, amiben egszeket szeretnnk trolni. A trolsra MAX mret dinamikus tmbt hasznlunk. A sor a data tmbt hasznlja az adatok trolsra, a beginI s endI vltozkat hasznljuk arra, hogy a sor elejt s vgt jelljk.

    class IntQueue {

    private:

    int data[MAX];

    int beginI, endI;

    public:

    IntQueue() {

    beginI = endI = -1;

    }

    www.tankonyvtar.hu Adonyi Rbert, Pannon Egyetem

  • Sor adatszerkezet 25

    bool isEmpty() const;

    int dequeue();

    void enqueue(int);

    };

    int IntQueue::dequeue() {

    int tmp = -1;

    if(endI==-1)

    cout

  • 26 Adatstruktrk s algoritmusok

    vgrehajtani, ezrt a az elz elemekre is szksg van a lncolsok elvgzshez. Egyszeresen lncolt lista esetn nehzkess vlhat a megvalsts. Ktszeresen lncolt listra az egyszeresen lncolt helyett, mert a sor tulajdonsgai miatt mindkt vgn mveleteket kell tudnunk elvgezni. A sor hatkonysgt nvelheti, ha brmelyik irnybl meg tudjuk mondani az elz elem cmt s elhelyezkedst. Lncolt lista hasznlata esetn a sor bvthetsgnek nincsenek korltai, a dinamikus tmbbel ellenttben itt nem kell elre memriaterletet foglalni az elemek trolshoz. A 8. brn az elzleg bemutatott dinamikus tmbbel implementlt sor s a rajta elvgzett mveletek lthatak ktszeresen lncolt lista segtsgvel.

    8. bra: Sor megvalstsa ktszeresen lncolt lista segtsgvel

    Szmos szmtstechnikai alkalmazst tallhatunk sorok hasznlatra. Tipikus alkalmazsa a sor adatszerkezeteknek pldul a processzor vrakozsi sora, mely azokat a folyamatokat tartalmazza, melyek processzorra, futsra vrakoznak. Msik tipikus alkalmazsa a sor adatszerkezeteknek az opercis rendszerek esetn kt folyamat kztt az adatok kicserlsre, kommunikcira az opercis rendszer ltal biztostott trterlet. Ezt a trterletet puffernek nevezzk s ltalban sor adatszerkezet segtsgvel valstjuk meg. A jegyzetben is tallkozhatunk majd olyan algoritmusokkal, pldul a grfalgoritmusok kztt, melyek sor adatszerkezetet hasznlnak mkdsk sorn (pldul a grfbejrsra hasznlt algoritmus).

    Prioritsos (elsbbsgi) sor adatszerkezet Sok esetben az elz rszben ismertetett sor nem elg a feladat megoldshoz, mert a FIFO adatsorrendet ms elveket figyelembe vve fell kell rni. Ilyen elv lehet pldul a sorban trolt adat fontossga, prioritsa. A prioritsos sor/elsbbsgi sor (priority queue) a FIFO elvet egy prioritssal kiegsztve elszr a magasabb prioritssal rendelkez elemeket szolgltatja. Az azonos prioritssal rendelkez elemek kztt a FIFO elv rvnyesl. Ilyen pldt tallhatunk pldul egy krhz srgssgi osztlyn, ahol a slyosabb srlteket (magasabb priorits) ltjk el elszr, s csak utna gondoskodnak az enyhbb srltekrl.

    www.tankonyvtar.hu Adonyi Rbert, Pannon Egyetem

  • Sor adatszerkezet 27

    Adonyi Rbert, Pannon Egyetem www.tankonyvtar.hu

    A prioritsos sorhoz nehz olyan hatkony implementcit tallni, melybe viszonylag gyorsan lehet elemet berakni s kivenni. Mivel beraksra az elemek eltr prioritssal rkeznek, ezrt kivtel esetn nem felttlenl a sor legels eleme lesz az, aminek a legnagyobb a prioritsa s ki kell venni a listbl. Alapveten ktfajta mdon lehet prioritsos sort ltrehozni lncolt lista, vagy dinamikus tmb segtsgvel.

    Amikor berakunk egy j elemet, akkor a prioritst figyelembe vve szrjuk be, azaz a prioritsnak megfelel sorrendben troljuk az elemeket.

    A kivtelkor keressk meg a megfelel prioritst, figyelembe vve a FIFO elvet is. A prioritsos sor hatkony implementlsra hasznlhatjuk a ksbbiekben bemutatott

    kupac tulajdonsgot teljest binris ft is.

  • 28 Adatstruktrk s algoritmusok

    Binris fa adatszerkezet A lncolt lista ltalban rugalmasabb eszkz adatok trolshoz, azonban lineris/szekvencilis tulajdonsga miatt nehz vele hierarchikus adatszerkezetet ltrehozni. Habr a verem s a sor is valamilyen rtelemben hierarchikus, azonban itt ez a hierarchia csak egy dimenzit takar. Az objektumok hierarchikus trolsra sokkal alkalmasabb a fa adatszerkezet.

    A grf egy olyan adatszerkezet, mely cscsokat/csompontokat s a cscsok kztti leket/sszekttetseket tartalmaz. A fa egy olyan specilis grf, mely brmely kt cscst pontosan egy t kti ssze, azaz a fa egy sszefgg s krmentes grf.

    A fban cscsokat (node) s a cscsok kztti kapcsolat (hierarchia) szervezsre leket (arc) klnbztetnk meg. A fa egy olyan hierarchikus adatszerkezet, melyben egy cscsnak legfeljebb egy megelzje/szlje (parent) lehet, azonban akrhny rkvetkezje/gyermeke lehet. Azokat a cscsokat, melyeknek egyetlen gyermekk sincs levlnek (kls cscs), azt a cscsot, melynek nincs szlje gykrnek nevezzk (root). Azokat a cscsokat, melyek nem kls cscsok, bels cscsoknak nevezzk. Hagyomnyosan a fkat a hierarchinak megfelelen szintekbe szervezve brzoljuk. Egy szinten azok a cscsok helyezkednek el, amelyek ugyanolyan tvolsgba vannak a gykrtl. Az brkon ltalban a gykr cscsot legfell, a legfels szinten szerepeltetjk. A 9. bra megfelelen egy ft brzol.

    9. bra: Fa adatszerkezet

    Az elz brn lthat ft brzolhatjuk Venn-diagrammal, vagy halmazokkal is. Az elz brn szerepl grf halmazokkal brzolva:

    A={G, K}, G={J, W, E}, K={V}

    A 9. brn lthat fa Venn-diagrammal brzolva a 10. brn lthat. A Venn-diagrammal brzolhatjuk a halmazok kztti sszefggseket s gy ezzel a fa adatszerkezetbl ered hierarchit. Hasonltsuk ssze a kapott Venn-diagrammot a kezdetben vizsglt fa adatszerkezettel.

    10. bra: Fa brzolsa Venn-diagrammal

    www.tankonyvtar.hu Adonyi Rbert, Pannon Egyetem

  • Binris fa adatszerkezet 29

    A fa defincija alapjn egy cscsnak akrmennyi gyermeke lehet. A fkat osztlyozhatjuk az alapjn, hogy egy cscsnak legfeljebb mennyi gyereke lehet. Azokat a fkat, melyeknl brmely cscs legfeljebb kt gyermeket tartalmaz binris fknak (binary tree) nevezzk. A binris fa teljes (full binary tree), ha minden nem-levl cscsnak pontosan kt gyerek cscsa van s minden levlbl ugyanolyan hossz ton rhet el a gykr. A majdnem teljes binris fa egy olyan fa, mely az utols szintjt kivve teljesen kitlttt, azonban az utols szinten csak egy adott cscsig vannak elemek (balrl jobbra). Az n cscs, majdnem teljes binris fa O(log n) szintet tartalmaz. Binris ft tbbflekppen is implementlhatunk. Egyik lehetsg, ha tmbt hasznlunk a binris fa elemeinek a trolsra, a msik lehetsg, ha egy lncolt lista segtsgvel troljuk a fa adatait. A 11. brn egy majdnem teljes binris fa s az azt brzol tmb lthat.

    11. bra: Majdnem teljes binris fa hagyomnyos mdon brzolva s tmbben trolva

    A fa brzolshoz hasznlt tmbt szintenknt, fentrl lefele haladva s szinten bell balrl jobbra lpkedve tltjk fel. Mivel egy h szintet tartalmaz binris fa legfeljebb 2h+1-1 cscsot tartalmaz, ezrt elre tervezni tudjuk a binris fa trolshoz szksges tmb mrett. A tmbben az i. index elem gyerekei a 2i. s a 2i+1. index elemek, az i. index elem szlje pedig az i/2. index elem. (Megj.: C s a C++ programozsi nyelvben a tmb indexelse nulltl indul, ezrt fa tmbbel val brzolsa esetn gondoskodjunk errl a tmb indexek kezelsekor.)

    Binris fa implementlsa mutatkkal A majdnem teljes binris fa tmbbel val trolsa helyett ebben a fejezetben olyan adatszerkezetet mutatunk be, mely mutatkat hasznl a fa cscsok kztti kapcsolatok trolsra. A mutatkat hasznl adatszerkezet brmely binris fa trolsra alkalmas, nem szksges hozz a majdnem teljessg tulajdonsga. Korbban lthattuk, hogyan lehet lncolt listba elemeket elhelyezni. A mutatkat hasznl fa adatszerkezet a lncolt listhoz hasonlan biztostja a cscsok fba val szervezdst.

    Binris fa trolshoz egy fa cscsnak ismernie kell a belle elrhet jobb s a bal oldali rszft, amihez egy cscsnak kt olyan mutatt kell tartalmaznia, amelyek cscs tpus objektumokra mutatnak. A kvetkez mintafeladatban egy egsz rtkeket trol binris fa adatszerkezetet s a hozz kapcsold metdusokat fogjuk ltrehozni. Minden binris fa cscspont hrom adatmezt tartalmaz: az adat trolshoz szksges (data), a bal (left) s a jobb (right) oldali rszfa mutatit (megj. bizonyos feladatoknl, pldul binris keresfk, szoks mg egy szl pointert is trolni a hatkonysg nvelsnek cljbl).

    struct IntTreeNode {

    int data;

    IntTreeNode *left;

    IntTreeNode *right;

    Adonyi Rbert, Pannon Egyetem www.tankonyvtar.hu

  • 30 Adatstruktrk s algoritmusok

    }

    A left s a right mutat abban az esetben, ha egy cscsnak nincs bal, vagy jobb oldali rszfja ezt NULL rtkkel jelzi. A 12. brn egy mutatkkal szervezett binris fa adatszerkezetet lthatunk. A fa gykr eleme a 43 rtket trolja, a fa hrom levl cscsot tartalmaz.

    12. bra: Binris fa mutatk segtsgvel brzolva

    Binris fa cscsainak megszmllsa A binris fa brmely cscsbl elrhet rszfa szintn egy binris ft alkot. Ennek a rekurzv tulajdonsgnak a kihasznlsval knnyen megvalsthatunk egy olyan rekurzv eljrst, mely a binris fa cscsait szmolja meg. Ezt az eljrst a countIntNodes() fggvny segtsgvel implementltuk.

    int countIntNodes(IntTreeNode *root) {

    if ( root == NULL )

    return 0;

    else {

    int count = 1;

    count += countIntNodes(root->left);

    count += countIntNodes(root->right);

    return count;

    }

    }

    A cscsokat megszmll algoritmust legegyszerbb rekurzv mdon szervezni. A rekurzv megllsi felttelt a mutat NULL rtke biztostja. Amennyiben a rszfra mutat rtk nem NULL, akkor ssze kell adni a jobb oldali s a bal oldali rszfban szerepl cscsok szmt.

    www.tankonyvtar.hu Adonyi Rbert, Pannon Egyetem

  • Binris fa adatszerkezet 31

    Az algoritmust rekurzi nlkl is meg lehet valstani. A problma a fban bejrt t trolsbl s nyomkvetsbl addik. A rekurzv fggvny hvsok sorn egy verem adatszerkezetbe kerlnek a hv fggvnyek. A rekurzv hvsokat egy sajt verem adatszerkezettel is helyettesthetnnk.

    Binris fa bejrsa A fa bejrs egy olyan mvelet, mely sorn a fa minden cscst pontosan egyszer ltogatjuk meg. A fa bejrsa felfoghat gy is, hogy valamely mdszernek megfelelen egyms utn tesszk a fa cscsait, vagyis linearizljuk a ft. A bejrstl fggen ms-ms sorrendben rakhatjuk sorba a fa cscsait. Mivel n darab klnbz cscsnak n! sorrendje lehetsges, ezrt n! klnbz bejrs ltezik. Ezeknek a nagy rsze gyakorlati rtelemben nincs jelentsge, de vannak olyan fa bejrsok, melyek bizonyos alkalmazsokban hasznunkra vlhat. Ezek kzl a legfontosabb kett bejrst, a szlessgi s a mlysgi fa bejrst rszletesen ttekintjk.

    Szlessgi bejrs Szlessgi (szintfolytonos, BFS, breadth-first search/traversal) bejrs esetn a gykrtl elindulva haladunk lefele a szinteken keresztl. Egy cscsot akkor jrhatunk be, ha a fltte lev szintek cscsain mr jrtunk. A feladatot egy iteratv algoritmussal oldhatjuk meg. A soron kvetkez cscsok trolsra egy IntTreeNode* mutatkat tartalmaz sort (queue) hasznlhatunk. A sor kezdetben a gykr cscsot tartalmazza. Minden egyes iterciban kivesszk a sor els elemt s a kivett elem gyermekeit berakjuk a sor vgre.

    void BFSIntTree(IntTreeNode *root) {

    IntTreeNodeQueue queue;

    IntTreeNode *p;

    if(root != 0)

    queue.enqueue(root);

    while(!queue.isEmpty()) {

    p = queue.dequeue();

    cout data left != 0)

    queue.enqueue(p->left);

    if(p->right != 0)

    queue.enqueue(p->right);

    }

    }

    A 12. brn lthat binris fra a szlessgi bejrs a kvetkez sorrendben rja ki a fa cscsaiban trolt rtkeket: 43, 1, 3, 10, 63 s 12.

    Mlysgi bejrs Mlysgi bejrs (DFS, depth-first search/traversal) esetn a gykrtl indulva haladunk olyan mlyre a szinteken, ameddig csak lehet. Ha mr nem lehet mlyebbre haladni, mert levlhez

    Adonyi Rbert, Pannon Egyetem www.tankonyvtar.hu

  • 32 Adatstruktrk s algoritmusok

    rtnk, vagy pedig minden elrhet cscs megltogatsra kerlt, akkor visszalpnk az elz szintre s errl a szintrl prblunk msik cscsok irnyba tovbbhaladni lefel.

    Mlysgi bejrs megvalsthat egy rekurzv fggvnnyel. A rekurzv fggvny pldul megvalsthat gy, hogy addig, amg a bal oldali rszfja ltezik egy cscsnak haladjunk a bal oldali rszfn keresztl lefele. Ha nem tud a baloldali rszfkban tovbbhaladni, akkor visszalps s a jobb oldali rszfk feldertse trtnik.

    A mlysgi bejrs tbbflekppen is megvalsthat attl fggen, hogy a jobb-, baloldali rszfa s az aktulis cscs feldolgozsnak mi a sorrendje. Hrom olyan sorrendet klnbztetnk meg, ami fontos szerepet tlt be informatikai algoritmusokban:

    Preorder bejrs: aktulis cscs baloldal jobboldal Inorder bejrs: baloldal aktulis cscs jobboldal Postorder bejrs: baloldal jobboldal aktulis cscs

    A preorder, inorder s postorder fa bejrs rekurzv fggvnyekkel a kvetkezkppen implementlhat:

    void Preorder(IntTreeNode *p) {

    if(p!=0) {

    cout data;

    Preorder(p->left);

    Preorder(p->right);

    }

    }

    void Inorder(IntTreeNode *p) {

    if(p!=0) {

    Inorder(p->left);

    cout data;

    Inorder(p->right);

    }

    }

    void Postorder(IntTreeNode *p) {

    if(p!=0) {

    Postorder(p->left);

    Postorder(p->right);

    cout data;

    }

    }

    A 12. bra binris fja a klnbz tpus mlysgi bejrsok esetn a kvetkez sorrendben rja ki a fban trolt rtkeket:

    Preorder: 43, 1, 10, 3, 63, 12

    www.tankonyvtar.hu Adonyi Rbert, Pannon Egyetem

  • Binris fa adatszerkezet 33

    Inorder: 10, 1, 43, 63, 3, 12 Postorder: 10, 1, 63, 12, 3, 43

    A Preorder, Inorder s Postorder fa bejrsok termszetesen megvalsthatak rekurzi nlkl is oly mdon, hogy a rekurzv fggvnyhvsokat egy veremmel helyettestjk. Mindhrom bemutatott bejrs esetn minden fa cscs pontosan egyszer kerl be a trolba, ezrt az algoritmusok komplexitsa O(n), ahol n a fa cscsainak szma.

    Binris keresfa Egy adott rtk tmbben val megkeresse tlagosan a tmbmret felvel megegyez lpssel oldhat meg. Ha a tmb elemeket rendezve troljuk, akkor a keress ennl mg hatkonyabban oldhatjuk meg a binris keress mdszervel. Binris (vagy logaritmikus) keress sorn pldul a tmb kzps elemnek megvizsglsval el tudjuk dnteni, hogy a rendezett tmb elejn, vagy a vgn tallhat a keresett rtk. Egy-egy ilyen sszehasonltssal a tmb aktulis elemeinek a felt kizrhatjuk a keressbl, egszen addig mg a kizrsok utn a vizsglatban marad tmbelemek szma egy, vagy kett lesz.

    A keress a rendezett tmbben a binris keress mdszervel O(log n) id alatt vgrehajthat. Ugyanakkor a rendezett tmbbe val j elem beszrs ugyanolyan erforrs ignyes mvelet mint a nem rendezett tmb esetn. Azrt hogy a tmb rendezett maradjon a beszrs utn is meg kell keresni az j elem helyt, s ettl a helytl kezdden a tmb vgn lev tmbelemeket eggyel el kell mozgatni htrafel, hogy biztostsuk a helyet az j tmbelem szmra. Hasonlan a rendezett tmbbl val elem trlse is a tmb megmarad elemeinek mozgatst eredmnyezi. Ezeket az elemek mozgatsval jr mveleteket kerlhetjk el, ha a rendezett tmb helyett rendezett listban troljuk az rtkeket. Ugyanakkor a rendezett lncolt listban nehz az elemek kzvetlen cmzse (pldul a 16. pozciban val elem megkeresshez a lista fejtl indulva vgig kell lpkedni a 16. pozci eltt szerepl sszes listaelemen).

    Mind lncolt listban, mind tmbben lehet rendezett mdon adatot trolni (pl. nvekv sorrendben). Egy rendezett tmb vagy lista esetn egy j adat hozzadsakor meg kell keresni a rendezsnek megfelel pozcijt az j adatnak, majd ebbe a pozciba be kell lncolni, vagy a tmbbe beszrni. A megfelel pozci megkeresshez mindkt adatstruktra esetn az elemek vgignzst s sszehasonltst kell tennnk. Egy bizonyos adatmennyisgig a lncolt lists s a tmbs megolds is jl hasznlhat. Az adatok rendezetten val trolsra egy sokkal hatkonyabb eszkz, ha binris keresft hasznlunk. A binris keres fa tmb s a lncolt listban val rendezett mdon val trols elnys tulajdonsgait egyesti egy adatszerkezetbe.

    A binris keresfa egy binris fa, melyre teljesl a binris keresfa tulajdonsg. A binris keresfa tulajdonsg szerint brmely cscs esetn teljeslnie kell, hogy a cscs bal oldali rszfjban a cscs rtknl kisebb, a jobb oldali rszfjban pedig csak nagyobb vagy egyenl rtkek szerepelhetnek. A 13. brn binris keres tulajdonsgot teljest fa lthat.

    13. bra: Binris keres tulajdonsgot teljest fa

    Adonyi Rbert, Pannon Egyetem www.tankonyvtar.hu

  • 34 Adatstruktrk s algoritmusok

    A binris keresfa trolsra hasznlhatjuk a binris fk trolsra bemutatott adatszerkezeteket. Ha van egy binris keresfnk, akkor abban megvalsthatjuk a keress mveletet. A keress mvelet sorn a binris keresfa tulajdonsgot kell csak sorozatosan kihasznlni. Ha a keresett rtk megegyezik az aktulis cscs rtkvel, akkor megtalltuk, amit kerestnk, ha kisebb nla, akkor a bal oldali, ha nagyobb nla, akkor a jobb oldali rszfban kell rekurzv mdon tovbb keresni.

    A kvetkez pldban egy osztlyt hozunk ltre binris keres fa megvalstsra. A binris keresfhoz a korbban ismertetett binris fa adatszerkezetet hasznljuk. Ebben a binris fa adatszerkezetben egsz rtkek binris fban val trolsra van lehetsgnk. A fa cscsainak trolsra a kvetkez osztlyt hasznljuk:

    class BSTIntNode{

    public:

    BSTIntNode() {

    left = right = 0;

    }

    int key;

    BSTIntNode *left, *right;

    }

    A binris keresfhoz a BSTIntNode osztlyt hasznljuk a binris fa felptsre. A binris keresft a BST osztly segtsgvel implementltuk. A BST osztlyban a root adattag mutatja a binris keresfa gykert. A konstruktorban szerepe az adattagok inicializlsa, a destruktor feladata pedig a felptett binris keres fa lebontsa, a lefoglalt cscsok felszabadtsa. Az osztlyban lehetsget kell biztostani a binris keres fa ptsre s mdostsra, az ezekhez szksges fggvnyeket jelenleg nem implementljuk.

    class BST {

    public:

    BST() { root = 0; }

    ~BST() { }

    bool isEmpty() const { return root==0; }

    int searchTree(const int element) {

    return search(root, element);

    }

    protected:

    int search(BSTIntNode*, const int) const;

    private:

    BSTIntNode *root;

    }

    www.tankonyvtar.hu Adonyi Rbert, Pannon Egyetem

  • Binris fa adatszerkezet 35

    A BST osztlyban a searchTree metdust hasznljuk arra, hogy egy adott rtk szereplst ellenrizzk a binris keresfban. A keresfban minden esetben a gykrelemtl indtjuk a keresst. A keress vgrehajtshoz egy bels protected metdust hasznlunk, mely iteratv mdon ellenrzi, hogy a keresett elem szerepel-e a fban? Az algoritmus minden egyes iterciban egy sszehasonltst vgez: a keresett rtk megegyezik-e, az aktulis cscsban trolt rtkkel, kisebb, vagy nagyobb-e nla. Az sszehasonlts eredmnytl fggen megtallja az rtket, vagy eldnti, hogy melyik rszfban kell tovbb keresnie (a msik rszfa kizrhat a tovbbiakban a keressbl). A search metdust a kvetkezkppen implementlhatjuk.

    int BST::search(BSTIntNode *p, const int element) const {

    while(p != 0) {

    if(element == p->key)

    return p->key;

    else if(element < p->key)

    p = p->left;

    else

    p = p->right;

    }

    return 0;

    }

    Keress sorn legrosszabb esetben, amikor a keresett rtk nem tallhat meg a binris keres fban, vagy levl szinten van meg benne, akkor a fa magassga szm itercit kell vgrehajtani. Ha az rtk valamely magasabb szinten tallhat, akkor ennl kevesebb sszehasonltssal megtalljuk a keresett elemet.

    Binris keres fa esetn inorder fa bejrssal visszakapjuk a fban trolt rtkeket nvekv sorrendben. A binris keres fa tulajdonsg biztostja, hogy inorder bejrs esetn minden bal oldali rszfban szerepl cscs elbb kerl kirsra, mint az aktulis cscs s a jobb oldali rszfban szerepl cscsok pedig ksbb.

    Ha egy binris keresfba j elemet szeretnnk berakni, akkor meg kell keresni azt az els olyan szabad pozcit, melybe ha beszrjuk az j elemet a binris keres fa tulajdonsg nem srl. Ennek a pozcinak a megkeresshez hasznlhatjuk a search fggvnyben bemutatott itercit. Ha megtalltuk azt a helyet, ahova belncolhatjuk az j rtket, akkor egy j cscs lefoglalsval s a binris keres fhoz val csatolsval elvgezhetjk a beszrs mveletet.

    A trls mvelet esetn tbb esetet kell megvizsglni. Amennyiben a trlend elemnek nincs gyermeke, akkor csak a szl megfelel (left/right) mutatjt. Ha a trlend elemnek pontosan egy gyermeke van, akkor az elem trlse megvalsthat, ha egyszeren kilncoljuk a fbl, azaz a szljnek a megfelel (left/right) mutatjt a trlend elem gyermekre irnytjuk. Ha a trlend elemnek kt gyermeke is van, akkor azt a legkzelebbi rkvetkez elemmel cserljk ki a benne trolt rtket, melynek nincsen bal oldali rszfja. A kicserls utn a gyermek nlkli, vagy az egy gyermekes elem trlsnek szablyai alapjn vgezzk el az elem trlst.

    A keress s a beszrs akkor maradhatnak hatkony mveletek a binris keresfban, ha a fa kiegyenslyozott (balanced) marad. Akkor kiegyenslyozott egy binris keres fa, ha a gykrbl a levelekbe vezet utak kzel azonos hosszsgak, azaz minl kzelebb van a majdnem teljes binris fkhoz. Ms szavakkal brmely cscs esetn a jobb s a bal oldali binris rszfban kzel azonos mennyisg cscs szerepelhet. A tkletesen kiegyenslyozott binris Adonyi Rbert, Pannon Egyetem www.tankonyvtar.hu

  • 36 Adatstruktrk s algoritmusok

    keres fban a rszfkban szerepl cscsok szmnak klnbsge legfeljebb egy. Ilyen tkletesen kiegyenslyozott ft nehz folyamatosan karbantartani, azonban egy vletlenszeren bvl s cskken binris keresfa esetn egy nagyjbl kiegyenslyozott binris keresft kapunk. A kiegyenslyozott binris keresfban egy keressi lpsben az egyik rszft kizrjuk a keressbl, ezzel krlbell a felre cskkentjk azoknak a cscsoknak a szmt, amiket figyelembe kell venni a tovbbiakban.

    Binris keres fban a legkisebb elemet megkaphatjuk a gykr elemtl a bal oldali rszfkban levl szintek fel lpegetve.

    int BST::minimum(BSTIntNode *p) const {

    while(p->left != 0) {

    p = p->left;

    }

    return p->key;

    }

    Hasonlan a legkisebb elem keresshez a legnagyobb elemet megkaphatjuk a jobb oldali rszfkban a levl szint fel haladva.

    int BST::maximum(BSTIntNode *p) const {

    while(p->right != 0) {

    p = p->right;

    }

    return p->key;

    }

    Piros-fekete s AVL fk A piros-fekete fa olyan specilis binris keres fa, melyben minden cscshoz hozzrendelnk egy sznkdot (piros/fekete). A sznezsre korltozsok bevezetsvel biztosthat, hogy a fa kiegyenslyozott maradjon oly mdon, hogy a fban a gykrbl indul leghosszabb t hossza nem lehet nagyobb, mint a gykrbl indul legrvidebb t hossznak a ktszerese.

    Az AVL fa olyan binris fa, mely magassga kiegyenslyozott, azaz brmely fa cscsra teljesl, hogy a cscs bal oldali rszfjnak s a jobb oldali rszfjnak a magassga legfeljebb 1-el klnbzik.

    Kifejezsek trolsa binris fval Binris fk egyik fontos alkalmazsa aritmetikai s logikai kifejezsek trolsa s kirtkelse lehet. Ennl az alkalmazsnl elengedhetetlen, hogy a trols sorn egyrtelm legyen a kifejezs s a binris fa kapcsolata azrt, hogy a kifejezs kirtkelsvel egyrtelmen a matematikailag helyes megoldst kapjuk.

    Az 1920-s vekben egy lengyel matematikus, Jan Lukasiewicz vezetett be egy olyan specilis, zrjeleket nem tartalmaz formt az aritmetikai kifejezsek brzolsra, amelybl a mveletek elvgzsnek sorrendje egyrtelmen addik. Ezt az brzolst lengyel formnak nevezzk. Habr a lengyel forma kevsb olvashat brzols, mint a zrjeleket hasznl

    www.tankonyvtar.hu Adonyi Rbert, Pannon Egyetem

  • Binris fa adatszerkezet 37

    hagyomnyosan elterjedt brzols, de a szmtstechnikban fordtknak s rtelmezknek ez a formula knnyebben kirtkelhet s kezelhet brzolst ad.

    Vegyk pldul a 4-5*2 aritmetikai kifejezst. A kifejezs rtke fgg a kirtkels sorrendjtl, amit a zrjelezssel irnythatunk: (4-5)*2 = -2, ugyanakkor 4-(5*2) = -6. A kifejezs lengyel formjbl knnyen pthet egy olyan binris fa, mely tartalmazza a kirtkelskor kvetett sorrendet (azaz a zrjelezst s a mveleti jelek precedencijt). A 14. brn kt binris ft lthatunk, amelyek a kt klnbz zrjelezst jelentik meg. A binris fk egyrtelmen brzoljk az adott kifejezst. Levl szinten tallhatak a szmok, kztes cscsokban pedig a mveletek. Ahhoz, hogy egy cscs rtkt megkapjuk ki kell rtkelni elbb a jobb s a bal oldali rszft, majd utna tudjuk a kapott eredmnyekkel a cscsban szerepl mveletet elvgezni.

    14. bra: Aritmetikai kifejezs brzolsa binris fval

    Vegyk szre, hogy a fa nem tartalmazza a zrjeleket, ugyanakkor egyrtelmen lerhat vele az aritmetikai kifejezs. A korbban ismertetett binris fa bejrsra bevezetett inorder, preorder s postorder fa bejrsokkal egy-egy kifejezst kapunk. A bal oldali binris fa esetn a preorder bejrs a * - 4 5 2 sorrendhez, az inorder a 4 - 5 * 2, mg a postorder a 4 5 - 2 * sorrendhez vezet. A msodik fnl a preorder a - 4 * 2 5, az inorder a 4 - 2 * 5, a postorder pedig a 4 2 5 * - sorrendhez vezet. Ezek kzl a binris fa bejrsok kzl az inorder nem alkalmas, hogy egyrtelmen lerja az elvgzend matematikai mveletek sorrendjt, hiszen mindkt fa esetn ugyanazt a kifejezst generlja. A msik kt bejrs azonban alkalmas az egyrtelm brzolsra majd a feldolgozsra. Jelentsgk miatt a preorder bejrssal kapott kifejezst prefix, a postorder bejrssal kapott kifejezst pedig postfix kifejezsnek nevezzk. A prefix brzolsban a mvelet megelzi az operandusokat, a postfixben az operandusok elbb szerepelnek, mint maga a mvelet. Vannak olyan programozsi nyelvek, melyek prefix (LISP) s vannak olyanok, melyek postfix (LOGO) jellst hasznlnak. Mind a kifejezst lengyel formra alakt, mind a lengyel formbl a kifejezs rtkt kiszmt algoritmus egy-egy szp pldja a verem alkalmazsnak.

    Kupac adatszerkezet A kupac (heap) egy olyan specilis binris fa, melyre teljesl az, hogy brmely cscs rtke nem kisebb mint a cscs brmely gyereknek az rtke, tovbb a fa majdnem teljes, azaz a legals szint kivtelvel minden szinten teljesen kitlttt, a legals szinten balrl jobbra haladva egy adott cscsig az sszes elem megtallhat. A tovbbiakban az ilyen binris fkat kupac tulajdonsgot teljest binris fnak nevezzk. Tudjuk, hogy az n elemet tartalmaz majdnem teljes binris fa magassga legfeljebb O(log n).

    A majdnem teljes binris fa trolsra hasznlhatjuk a tmb adatszerkezetet (lsd 11. bra). A kupac tulajdonsgai miatt a tmb legnagyobb eleme a fa gykreleme, amit a tmb els indexn trolunk. Kupac segtsgvel gyorsan vissza tudjuk adni a legnagyobb elemet, azonban mivel a tbbi elem nem rendezett, ezrt ugyanazokhoz az elemekhez tbb klnbz kupac is pthet. A 15. brn egy kupacot lthatunk. Kupac tulajdonsgot s a kupacot a ksbbiekben a kupacrendezs algoritmusban fogjuk hasznlni. A kupac a rendezs mellett a prioritsos sorok ltrehozsban kap fontos szerepet. Hasonlan pthet olyan kupac is, melynek tetejn

    Adonyi Rbert, Pannon Egyetem www.tankonyvtar.hu

  • 38 Adatstruktrk s algoritmusok

    www.tankonyvtar.hu

    (gykerben) a legkisebb elem tallhat, gy beszlhetnk maximum s minimum kupacrl, aszerint, hogy a maximlis, vagy minimlis elem kerl a kupac tetejre.

    15. bra: Kupac tulajdonsgot teljest binris fa

    Adonyi Rbert, Pannon Egyetem

  • Rendezs 39

    Rendezs Adatok hatkony kezelshez elengedhetetlen az adatokat valamilyen szempont alapjn rendezve trolni. Mindennapi pldk mutatjk, hogy meg lehet tallni valamit rendezetlen adatok kztt is, azonban a keresst felgyorsthatja, ha az adatok rendezve vannak (pl. knyvtr, telefonknyv). Kis adatmennyisg esetn (10-100-1000 darab) mindegy, hogy mennyire gyors, mennyire hatkony az algoritmus, mely a rendezst vgzi. Ha azonban az adatmennyisg nvekszik, a rendez algoritmus hatkonysga nagyban befolysolhatja az egsz alkalmazs hasznlhatsgt.

    A rendezs els lpse a rendezsi elv meghatrozsa. A rendezsi elv kivlasztst ltalban az alkalmazs hatrozza meg. Szmok esetn a rendezsi elv lehet a nvekv, vagy a cskken sorrend. Nevek esetn ltalban bc szerinti sorrendet hasznlunk.

    A kvetkez rendez algoritmikusok esetn tmbben troljuk azokat az adatokat, melyekre az algoritmusok mkdst bemutatjuk. Az algoritmikusok sszehasonltson alapul helyben rendez algoritmusok, azaz a tmb elemek egymssal val sszehasonltsa s rtkek kicserlsvel hatrozzk meg a rendezett tmbt. Felttelezzk, hogy az adatok egsz szmok s a rendezsi elv a nvekv sorrend.

    Beszrsos rendezs A beszrsos rendezs a tmb elejn egy rendezett rsztmb lpsenknti bvtsvel hatrozza meg a teljes rendezett tmbt. A beszrsos rendezs (insertion sort) els lpseben a tmb els kt elemt hasonltja ssze (d[0] s d[1]), a tmb msodik elemt szrja be az egy hosszsg rendezett rsztmbbe. Ekkor az els kt eleme egymshoz kpest rendezve van. Kvetkez lpsben a harmadik elemmel (d[2]) kibvtve rendezi az els kt elemet. Az algoritmus megkeresi a d[2] helyt a d[0] s d[1] elemekhez kpest, beszrja a d[2]-t a helyre, a tbbi elem elcssztatsval kszti el a d[2] helyt. A k. lpsben az els k elem mr rendezve van. Az algoritmus azokat az elemeket, melyek nagyobbak mint a d[k] elem eltolja egy hellyel jobbra, gy kszt helyet a d[k] tmbelem szmra. Az algoritmus lpseinek s mkdsnek a szemlltetst a 16. brn lthatjuk.

    16. bra: Beszrsos rendezs mkdsnek szemlltetse

    Adonyi Rbert, Pannon Egyetem www.tankonyvtar.hu

  • 40 Adatstruktrk s algoritmusok

    A beszrsos rendezs egybegyazott for ciklusok segtsgvel implementlhat. A for ciklusok egybegyazsa jelzi az algoritmus komplexitst (O(n2)). A beszrsos rendezs C++ forrskdja a kvetkezkppen plhet fel:

    insertionSort(int d[], int size){

    int tmp;

    for(int i=1, j;i

  • Rendezs 41

    d ciklus kzben 1 4 9 8

    d ciklus kzben 1 4 9 8

    d ciklus utn 1 2 4 9 8

    i=4, tmp=8 0 1 2 3 4

    d ciklus eltt 1 2 4 9 8 d ciklus kzben 1 2 4 9

    d ciklus utn 1 2 4 8 9

    Kivlasztsos rendezs A kivlasztsos rendezs (selection sort) sorn az adatok msolsnak mennyisgt igyekszik cskkenteni oly mdon, hogy az algoritmus keres egy olyan elemet, ami nem a helyn tallhat, majd rgtn a vgleges helyre msolja. Els lpsben megkeresi a legkisebb tmbelemet, amit a tmb els helyn szerepl elemmel cserl ki. Innentl kezdve az els elemmel mr nem kell foglalkozni, elg a msodik elemmel kezdd tmbt rendezni.

    A beszrsos rendezshez hasonlan a kivlasztsos rendezs is ngyzetes jelleg algoritmus (O(n2). Az algoritmus egybegyazott for ciklusok segtsgvel implementlhat. A kivlasztsos rendezs C++ forrskdja a kvetkez:

    selectionSort(int d[], int size){

    int tmp,least;

    for(int i=0, j;i

  • 42 Adatstruktrk s algoritmusok

    ciklus az i. elemtl indulva keresi meg az i. elem s a tmb utols eleme kzl a legkisebb elem indext. A ciklus befejeztvel a legkisebb elem s az i. elem cserjt vgezzk.

    Az algoritmus viselkedsnek szemlltetsre rendezzk az 5 elembl ll 5, 3, 9, 2, 8 tmbt a selectionSort algoritmussal. A 17. brn lthatjuk az algoritmus futsa sorn a d tmb vltozst. Az i=1 iterciban a 2. s 5. elem kzl a legkisebbet kell megkeresni s kicserlni a 2. helyen ll elemmel. Mivel ebben a pldban a legkisebb elem ppen a 2. pozciban tallhat, ezrt nmagval kellene kicserlni. A selectionSort algoritmus ezekre az esetekre kiegszthet egy ellenrzssel, ami alapjn csak akkor hajtsuk vgre a csert, ha least vltoz nem egyenl az i vltozval (enlkl a kiegszts nlkl is helyesen rendezi a tmbt az algoritmus).

    17. bra: A selectionSort algoritmus lpseinek bemutatsa

    Bubork rendezs A bubork rendezs (bubble sort) bemutatshoz a rendezend tmbt brzoljuk vertiklisan, egy oszlopban. Az algoritmus a tmb aljtl felfele halad. Megvizsglja az egyms mellett ll elemeket s ha nem j a sorrendjk, akkor megcserli ket. Egy size mret tmb esetn elszr a d[size-1] s d[size-2] elemeket hasonltja ssze s cserli ki ket, ha szksges. Kvetkez sszehasonlts s az esetleges csere a d[size-2] s d[size-3] elemek kztt trtnik. Az sszehasonltsok s cserk egszen a tmb tetejig a d[1] s d[0] elemig trtnik. Ezzel, a tmb egyszeri vgignzsvel a tmb tetejre felbuborkoltattuk a tmb legknnyebb (legkisebb) elemt.

    A kvetkez lpsben ugyanezt a mdszert hajtjuk vgre, azonban most elg a tmb utols eltti elemig haladni felfele, hiszen a legkisebb elem mr a helyn van (d[0]). A tmb msodik vgigjrsval a kt legkisebb tmbelem a 0. s az 1. pozciban tallhat. Az algoritmus addig folytatdik, ameddig a tmb vgigjrs a legals elemek sszehasonltsra s cserjre redukldik.

    A bubork rendezs, hasonlan a korbbi rendezsi algoritmusok, is ngyzetes jelleg algoritmus (komplexitsa O(n2). Az algoritmus egybegyazott for ciklusok segtsgvel implementlhat. A bubork rendezs C++ forrskdja a kvetkez:

    bubbleSort(int d[], int size){

    int tmp;

    for(int i=0;ii;--j)

    if(d[j]

  • Rendezs 43

    tmp=d[j];

    d[j]=d[j-1];

    d[j-1]=tmp;

    }

    }

    Rendezzk a 5,3,9,2,8 egszeket tartalmaz tmbt a buborkrendez algoritmus segtsgvel. A 18. brn az algoritmus vgrehajtsa sorn azokat a lpseket brzoljuk, melyek sorn a tmbelemek cserje trtnt.

    18. bra: Bubork rendezs lpsei az 5,3,9,2,8 elemeket tartalmaz tmbre

    Kupac rendezs A kupac rendezs (heap sort) a kivlasztsos rendezs mkdst tekintve nagyon hasonlt r. Mindkt algoritmus kivlasztja az aktulisan legkisebb, vagy legnagyobb elemet a mg rendezetlen elemek kzl s berakja azt a rendezsnek megfelel helyre. Ezt a kivlasztst addig folytatjk, mg a tmb elemei rendezettek lesznek.

    A kupac rendezs a kupac tulajdonsgot kihasznlva rendezi a tmbt. Ha nvekv sorrendbe akarjuk rendezni a tmbt, akkor a kupacbl a legnagyobb elemet a tmb legutols helyre kellene tenni. A kupac tulajdonsg alapjn a legnagyobb rtk a binris fa gykrhez tartozik, ami a fa tmbbel val trolsa esetn a tmb legels elemnek felel meg. Az algoritmusban a kupac gykr elemt kicserljk a kupac (vagyis a tmb) legutols elemvel. A tmb utols eleme ezzel mr a legnagyobb rtk, ami mr a helyre kerlt, ezrt levlaszthatjuk a kupacrl (a kupac egyre kisebbre zsugorodik a tmbn bell). Ha a maradk elemeket kupacba rendezzk, folytathatjuk az algoritmust. Az algoritmus elindtshoz legels lpsben egy tmbbl kupacot kell ksztennk. A kupac rendezs a kvetkez lpseket tartalmazza: