Előadást letölteni
Az előadás letöltése folymat van. Kérjük, várjon
KiadtaRenáta Kerekesné Megváltozta több, mint 10 éve
1
Miskolci Egyetem Informatikai Intézet Általános Informatikai Tanszé k Pance Miklós Adatstruktúrák, algoritmusok előadásvázlat Miskolc, 2004 Technikai közreműködő: Imre Mihály, műszaki informatikus hallgató
2
Fák Alkalmazásuk: fájl rendszerek implementálása, aritmetikai kifejezések kiértékelése, keresés, a kereső műveletek O(log N) átlagos és worst case hatékonyságúak, kereső műveletek megvalósítása lemezen, stb. 2
3
Fák A fa definíciója: Rekurzívan: a fa csúcspontok gyűjteménye. Ez a gyűjtemény lehet üres, melyet jelöl, 3 különben a fa egy kitüntetett csúcsból, ami a fa gyökere (r) és 0 vagy több T 1, T 2, …, T k (al)fából áll, melyek gyökere egy irányított éllel kapcsolódik az r-hez. Minden (nem üres) alfa gyökere az r gyereke, és az r az alfák gyökerének szülője. root T1T1 T2T2 TKTK …
4
Fák Tehát egy fa N csúcspont gyűjteménye, melyek egyike a gyökér, és a csúcspontokat N-1 irányított él köti össze. 4 A B C D EF LKM H IJN P Q G
5
Fák A: gyökér, F-nek A a szülője, K, L, M a gyerekei Levelek (nincs gyereke): B, C, H, I, P, Q, K, L, M, N. Testvérek (ugyanaz a szülőjük): K, L, M. Nagyszülő, unoka… Útvonal (path): n 1 -ből n k -ba: n 1, n 2, …, n k, csúcspont sorozat úgy, hogy az n i+1 szülője n i ( ) Az útvonal hossza az élek száma: k-1. Minden csúcsból önmagához zérus hosszúságú út vezet. Minden csúcshoz a gyökértől pontosan egy út vezet. 5
6
Fák Az n i csúcs mélysége (depth): a gyökértől hozzá vezető, egyetlen út hossza. A gyökér mélysége 0. Az n i magassága: az n i –ből a levelekhez vezető utak közül a leghosszabb. Minden levél 0 magasságon van. A fa magassága: a gyökér magassága. Pl.: E mélysége 1, magassága 2 F mélysége 1, magassága 1 a fa magassága: 3 A fa mélysége: a legmélyebb levél mélységével egyenlő, ami mindig egyenlő a fa magasságával. 6
7
Fák Ha van út n 1 –ből n 2 –be, akkor n 1 az n 2 őse, és n 2 az n 1 egy leszármazottja. Ha, akkor valódi ős, leszármazott. A fa ábrázolása (implementációja): 1.minden csúcs az adatán felül mutatókat tartalmaz a gyerekeihez. Nem praktikus: a gyerekek száma nagyon változó, pazarlás. 2.minden csúcs gyerekeit láncolt listában tartjuk. type fap = ^facsucs facsucs = record elem: elemtipus; elsogyerek: fap; kovtestver: fap; end; 7
8
Fák a lefelé nyilak az elsőgyerek mutatók, a balról-jobbra nyilak a következő testvér mutatók. 8 A B C D E F LKM H IJN PQ G
9
Fák Egy alkalmazás: katalógus struktúra (Unix, Vax/VMS, DOS). A Unix fájl rendszerben a katalógus egy fájl a gyerekeinek listájával, hasonló a fenti típus deklarációhoz (azzal az eltéréssel, hogy a Unixban a direktory-nak van saját magára és szülőjére is mutatója). Listázása (egy katalógus összes fájl-ja) indenttel: procedure Dirlist(DF: dir_vagy_fajl; tab:integer); begin if DF érvényes bejegyzés begin print_name(tab, DF) if DF directory then FOR DF minden GY gyerekére Dirlist(GY, tab+1) end; end; 9
10
Fák Procedure PrintDir(DF: dir_vagy_fajl); Begin DirList(DF, 0 ); End; Ez a módszer a preorder lista: mivel a csúcspont nevének nyomtatása megelőzi a gyerekek feldolgozását. 10
11
Fák Egy másik szokásos módszer a postorder feldolgozás: a csomóponti munkát a gyereke kiértékelése után (post) végzi. Pl. az elfoglalt blokkok száma? (dir = 1) Function dir_size(DF: dir_vagy_fajl):integer; Var tm: integer; begin tm := 0; if DF érvényes bejegyzés then begin tm := filesize(DF); if DF directory then For DF minden GY gyerekére tm := tm + dir_size(GY); end; dir_size = tm; {kiírás} end; 11
12
Bináris fák Olyan fa, melyben egyetlen csúcsnak sincs kettőnél több gyereke: 12 root TLTL TRTR A bináris fák átlagos mélysége lényegesen kisebb N-nél: A bináris kereső fáké pedig : Sajnos a mélység lehet N-1 is. A B C D B wc
13
Bináris fák Implementációja: Hasonlít a kétszeresen láncolt listákéhoz. type bfap = ^bfacsucs bfacsucs = record elem : elemtipus; Left : bfap; Right : bfap end; bfa = bfap; A bináris fák a keresésen kívül sok fontos alkalmazással rendelkeznek a compiler tervezés területén. 13
14
Kifejezés fák A kifejezés fa levelei operandusok (konstans, változó), a többi csúcs operátor. Pl. (a+(b*c)) + (((d*e)+f)*g) (redundáns zárójelekkel) 14 + + a* bc * + g *f de
15
Kifejezés fák Inorder kiértékelés (infix): bal, csúcs, jobb 15 + + a* bc * + g *f de (a + (b * c)) + ((( d * e) + f ) * g)
16
Kifejezés fák Postorder kiértékelés (postfix): bal, jobb, csúcs 16 + + a* bc * + g *f de a b c * + d e * f + g * +
17
Kifejezés fák Preorder kiértékelés (prefix): csúcs, bal, jobb 17 + + a* bc * + g *f de + + a * b c * + * d e f g
18
Kifejezés fák A kifejezés fa felépítése Postfix kifejezés kifejezés fa Olvassuk a szimbólumokat, ha operandus, akkor létrehozunk egy 1 csúcspontú fát és pointerét a stackre tesszük (push) operátor, akkor levesszük a stackről (pop) a T 1, T 2 fákra mutató pointereket (T 1 –t először) és kialakítunk egy új fát, melynek gyökere az operátor és amelynek bal és jobb gyereke T 2 illetve T 1. Ennek az új fának a pointerét a stackre tesszük (push). 18
19
Kifejezés fák Pl. a b + c d e + * * 19 a b ab +
20
Kifejezés fák Pl. a b + c d e + * * 20 ab + cd e ab + c + de
21
Kifejezés fák Pl. a b + c d e + * * 21 ab + * c + de ab + * c + de *
22
Bináris kereső fa A bináris fák egyik fontos alkalmazása a keresésben, a csomópontokhoz kulcs értéket rendelünk, egész kulcs, dupla nincs (egyelőre). Bináris kereső fa: Minden X csúcsra teljesül, hogy a baloldali alfa minden csúcsában lévő kulcs kisebb mint az X-ben, a jobboldaliban pedig mindegyik nagyobb (a kulcsok rendezhetők). 22 6 8 2 4 1 3 6 8 2 4 1 3 7
23
Bináris kereső fa Műveletek: mivel a bináris fák átlagos mélysége O(log N), ezért rekurzív rutinokat írunk. Üres fa: procedure uresfa(var T:bkfap); begin T := nil; end; 23
24
Bináris kereső fa Keresés (Find): a T fa azon csúcsának pointerét adja vissza, aminek kulcsa X, vagy nil, ha nincs. Function Find(X: integer; T: bkfap) : bkfap; Begin If T = nil then Find := nil Else If X < T^.elem then Find := Find(X, T^.Left) Else If X > T^.elem then Find := Find(X, T^.Right) Else Find := T; End; 24
25
Bináris kereső fa Findmin: pointert ad vissza, nem az értéket, rekurzívan Function FindMin(T: bkfap) : bkfap; Begin If T = nil then FindMin := nil Else If T^.Left = nil then FindMin := T Else FindMin := FindMin(T^.Left) End; 25
26
Bináris kereső fa Findmax: pointert ad vissza, nem az értéket, ciklussal Function FindMax(T: bkfap) : bkfap; Begin If T <> nil then While T^.Right <> nil do T := T^.Right; FindMax := T; End; 26
27
Bináris kereső fa Insert: X-et a T-be, először lefelé haladva keressük a helyét, mint a Find-dal. Ha X megvan, akkor legfeljebb upgrade (vagy előfordulás növelés). Különben az utoljára érintett csúcspontnál beszúrjuk X-et. (Az ismétlődések a fa mélységét növelnék, inkább a gyakoriságukat számoljuk. Az azonos kulcsú rekordokat listában vagy pótfában tárolhatjuk.) 27
28
Bináris kereső fa Beszúrás pl.: 28 6 8 2 4 1 3 5 6 8 2 4 1 3 5
29
Bináris kereső fa Procedure Insert(X : elemtipus; var T: bkfap); Begin If T = nil then Begin New(T); If T = nil then nincs memória; Else Begin T^.elem := X; T^.Left := nil; T^.Right := nil; End; End 29
30
Bináris kereső fa Else Begin If X < T^.elem then Insert(X, T^.Left) Else If X > T^.elem then Insert(X, T^.Right) Else X már benne van; End; 30
31
Bináris kereső fa Törlés (Delete): Először megkeressük, ha 1.a csúcs egy levél, akkor azonnal törölhető, 2.a csúcsnak egy gyereke van, akkor a szülője pointerének átírása után a csúcs törölhető, 3.a csúcsnak két gyereke van, akkor az általános stratégia az, hogy ennek a csúcsnak a kulcsát a jobb alfa legkisebb kulcsával helyettesítjük. Mivel a jobb alfa legkisebb csúcsának nincs (nem lehet) bal gyereke a törlés egyszerű. 31
32
Bináris kereső fa Törlés 1. pl. 32 6 8 2 4 1 3 4 1 gyereke van 6 8 2 4 1 3
33
Bináris kereső fa Törlés 2. pl. 33 6 8 2 4 1 3 3.5 2 2 gyereke van 6 8 2 4 1 3 3.5 A 2-es jobboldali részfájának minimuma a 3 ez megy a törlendő helyére, őt pedig töröljük.
34
Bináris kereső fa Procedure Delete(X: elemtipus, var T : bkfap); Var Tmp : bkfap; Begin If T = nil then nem található X elem Else Begin If X < T^.elem then Delete(X, T^.Left) Else If X > T^.elem then Delete(X, T^.Right) Else {megvan a törlendő elem} Begin If T^.Left = nil then {csak jobb gyerek} Begin Tmp := T; T := T^.Right; Dispose(Tmp); End; 34
35
Bináris kereső fa Else If T^.Right = nil then {csak bal gyerek} Begin Tmp := T; T := T^.Left; Dispose(Tmp); End; Else {2 gyerek, a jobb részfa min-ával helyett.} Begin Tmp := FindMin(T^.Right); T^.elem := Tmp^.elem; Delete(T^.elem, T^.Right); End; 35
36
Bináris kereső fa Megjegyzés: kétszer keresi a jobb Min-t Lazy (lusta, lassú) (Lazy Susan) stratégia: törlésre jelöljük. Ha a valódi csúcsok száma pont annyi, mint a „törölteké” akkor a fa mélysége csak kicsit emelkedik. De visszahelyezésnél nem kell újra helyet foglalni. A fenti műveletekhez (Üres fa kivételével) O(log N) idő szükséges átlagosan. Az Insert/ Delete torzíthat ha az input előrendezett, akkor a fa a láncolt lista bonyolultabb megvalósítása, a törlést véletlenszerűen kellene a jobb oldali részfa Min- ával és a baloldali Max-ával végezni (helyettesíteni). 36
37
Bináris kereső fa Egyensúly: egyetlen csúcspontnak sem engedjük meg, hogy túl mélyre kerüljön. kiegyensúlyozott kereső fa, önrendező fák (minden művelet után újrastruktúráljuk a fát, hogy az elkövetkező műveletek hatékonyak legyenek). Egyensúlyi feltételek: 1. a bal és jobb alfák azonos magasságúak legyenek, ez sajnos nem erőlteti a sekély fa kialakítását, pl. (a gyökérre vonatkozóan): 37
38
Bináris kereső fa 2. vagy minden csúcsra vonatkozóan: csak a tökéletesen kiegyensúlyozott fák teljesíthetik, melyeknek 2 k -1 csúcsuk van. Ez ugyan biztosítja a kis mélységet, de túl szigorú. 3. a fa minden csúcsára érvényes, hogy a bal és jobb alfa magassága legfeljebb kismértékben térhet el. 38
Hasonló előadás
© 2024 SlidePlayer.hu Inc.
All rights reserved.