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ó
Splay fa Splay: kiszélesedik, lesarkít, ferdére vág Garantálja – üres fából kiindulva –, hogy M egymás utáni fa művelet legfeljebb O(M log N) idejű. Általában, ha M művelet wc teljes ideje O(M F(N)) akkor az amortizált futási idő O(F(N)), ezért a splay fa műveleteinek amortizált ideje O(log N). Az alapelv: ha elértünk egy csúcsot, akkor azt egy sor AVL fa forgatással a gyökérbe nyomjuk. (Sok alkalmazásban, ha egyszer megkerestünk egy elemet, akkor valószínű, hogy a közeljövőben újból keressük, ez az eset gyakoribb, mint gondolnánk.) ! Nem kell a magasság információ ! 2
Splay fa Egy nem működő egyszerű ötlet: Minden csúcsot az elérési úton a szülőjével megforgatunk. 3 A k1k1 B C D E F k2k2 k3k3 k4k4 k5k5 A B C D k2k2 k1k1 k3k3 k 1 -k 2
Splay fa 4 k 1 -k 3 k 1 -k 4 A B E k2k2 k1k1 k4k4 k3k3 C D A B F k2k2 k1k1 k5k5 k4k4 E k3k3 C D
Splay fa 5 k 1 -k 5 A k 1 ugyan a gyökérbe került, de a k 3 majdnem olyan mélyre került, mint a k 1 volt... A B k2k2 k1k1 k5k5 F k4k4 E k3k3 C D
Splay fa Splaying Továbbra is alulról-felfelé forgatunk. Legyen X egy csúcs az elérési útvonalon (nem gyökér). Ha X szülője a gyökér, akkor egyszerűen megforgatjuk őket, ez lesz az útvonalon az utolsó forgatás. Különben van szülője (P) és nagyszülője (G). 6
Splay fa 1. eset : X jobb gyerek és P bal gyerek (vagy fordítva) dupla forgatás mint az AVL-nél 7 A G B P X D C A B C D P X G X P G B C A D Zig-Zag
Splay fa 2. eset: X és P mindegyike bal (jobb) gyerek 8 A B C D X P G P X G B C A D B A P X C G D Zig-Zig
Splay fa Az előző példa így: 9 A k1k1 B C D E F k2k2 k3k3 k4k4 k5k5 A B E k2k2 k1k1 k4k4 k3k3 C D k5k5 F k 1 -k 2 -k 3 Zig-Zag (AVL dupla)
Splay fa A k 1 helyzete kiváló, az egész laposodott, nagyobb példán jobban látszik. 10 A B E k2k2 k1k1 k4k4 k3k3 C D k5k5 F C D k3k3 k4k4 k5k5 E F k2k2 k1k1 A B k 1 -k 4 -k 5 Zig-Zig
Splay fa Implementáció nem rekurzív + szülő pointer
Splay fa felülről-lefelé Az alap splay-fánál: az X elemet levélként beszúrtuk, utána egy sor forgatással (splay) az X a fa új gyökere lett. A keresés folyamán is végeztünk splay-t. Ha az elem nem található, akkor az elérési út utolsó csúcspontjára végeztük a splay-t. Ehhez a stratégiához a fát be kell járni a gyökértől lefelé, majd a splay-hez alulról-felfelé. Ezt vagy a szülő pointerekkel, vagy az elérési út stackre tételével tudjuk megvalósítani. Most a forgatásokat az elérési út mentén hajtjuk végre. Ez a gyakorlatban gyorsabb, O(1) plusz hely kell, és az amortizált időkorlát O(log N) marad. 12
Splay fa felülről-lefelé Az elérés bármely pontján az aktuális csúcs X, az alfájának gyökere, ez lesz a középső fa. Az L fa az X-nél kisebb, de az X alfájában nem szereplő csúcsokat tárolja. Az R hasonlóan a T fa X-nél nagyobb, de X alfájában nem lévő csúcsokat tárolja. Kezdetben X a T gyökere, L és R üres. 13
Splay fa felülről-lefelé Zig: 14 L A Y X B R L A Y X B R A középső fa új gyökere Y lesz. Az X és a B alfa az R legkisebb elemének bal gyereke lesz, így R-ben a legkisebb elem az X lesz. Az Y-nak nem kell levélnek lennie a Zig-hez. Ha egy Y-nál kisebb elemet keresünk és az Y-nak nincs bal gyereke (jobb gyerekének kell lennie), akkor a Zig-et alkalmazzuk.
Splay fa felülről-lefelé Zig-Zig: 15 LR A Z X C Y B L A Z R X C Y B
Splay fa felülről-lefelé Zig-Zag: 16 LR B Z X C Y A LR B Z X C Y A Forgatás valójában nem történt.
Splay fa felülről-lefelé Egyszerűsített Zig-Zag: 17 LR B Z X C Y A LR B Z Y C X A Így a Zig-Zag csak egy Zig lesz és Y a középső gyökér Z helyett.
Splay fa felülről-lefelé Az utolsó splaying után összerakjuk a fákat: 18 L A X B R A L X R B
Splay fa felülről-lefelé Példa: a 19-et keressük 19 ü ü
Splay fa felülről-lefelé Egyszerűsített Zig-Zag ( ): ü 12 5
Splay fa felülről-lefelé Zig-Zig ( )
Splay fa felülről-lefelé Zig (15-18):
Splay fa felülről-lefelé Összerakás: