1.Seminarska naloga Splay tree Lomljeno drevo Dvojiška drevesa Dvojiško drevo je bodisi prazno ali pa ga sestavlja posebej odlikovano vozlišče koren, ki ima levo in desno poddrevo. Levo in desno poddrevo sta spet dvojiški drevesi. Iskalno drevo Iskalno drevo je dvojiško drevo, za katerega velja, da so vsi elementi v levem poddrevesu (ki je tudi iskalno drevo) manjši od korena in v desnem poddrevesu (ki je tudi iskalno) večji od korena. Pri operacijah nad iskalnimi dvojiškimi drevesi, kot so vstavljanje, brisanje in iskanje elementa, pogosto pride do izrojevanja dreves (višina levega in desnega poddrevesa se močno razlikujeta). To težavo lahko odpravimo z uporabo lomljenih dreves. Lomljena drevesa Lomljena drevesa so dvojiška iskalna drevesa, ki se spremenijo (lomijo) ob vsakem posegu v drevo. To je pri iskanju elementa v drevesu, vstavljanju elementa v drevo in pri brisanju elementa iz drevesa. Lomljenje drevesa trenutni element premakne proti korenu drevesa oziroma v koren drevesa. Za lomljenje drevesa uporabljamo rotacije. -Pri vstavljanju element v drevo vstavimo v list drevesa. Nato z rotacijami dosežemo, da vozlišče s tem elementom postane koren drevesa. -Pri brisanju elementa iz drevesa vozlišče, s tem elementom, z zaporedjem rotacij najprej postane koren drevesa in nato ga s pomočjo rotacij zbrišemo iz drevesa. -Pri iskanju elementa v drevesu postane koren drevesa vozlišče z najdenim elementom. Za izvedbo rotacij na lomljenih drevesih poleg podatka o obeh sinovih, potrebujemo tudi podatek o očetu. Drevo lomimo iz dveh razlogov. Prvi je ta, da s tem preprečimo izrojevanje drevesa. Pri majhnem številu element lahko do položaja, ko je drevo izrojeno tudi pride, vendar pri večjem številu elementov in večjem številu operacij nad drevesom to v splošnem ne bo izrojeno, ampak uravnoteženo. Drugi razlog za lomljenje pa je, da z lomljenjem podatek, ki ga obravnavamo (iščemo, vstavljamo,...), pride v korensko vozlišče. Ker pri številnih uporabah pogosto pride do položaja, ko več zaporednih operacij zahteva iste ali sorodno velike podatke, s tem pohitrimo izvajanje.
Lomljenje dreves rotacije Lomljenje drevesa premakne z rotacijo dani element v koren drevesa. Rotacija je postopek, ki zamenja vlogo sinov in očeta v iskalnem dvojiškem drevesu. Preoblikovano drevo je ravno tako iskalno dvojiško drevo. Odvisno od primera uporabljamo enojne in dvojne rotacije. Dvojna rotacija je kombinacija dveh enojnih. Rotacije so lahko leve ali desne. Pri lomljenju lahko nastopijo štirje primeri: 1.Kadar je iskani element X v korenu drevesa, rotacija ni potrebna. 2. Kadar je oče vozlišča z elementom koren drevesa, uporabimo enojno rotacijo. - Do desne rotacije pride, če je iskani element X levi sin. Vloga očeta in sina se zamenja. V primeru, da obstajajo poddrevesa, se desno poddrevo vozlišča z obravnavanim elementom (poddrevo E) pripne na očeta kot levo poddrevo.
-Do leve rotacije pride, če je iskani element X desni sin. Leva rotacija je zrcalna desni. 3.Kadar sta vozlišče z obravnavanim elementom in oče oba leva ali oba desna sinova svojih očetov uporabimo dvojno rotacijo. - Desno-desno rotacijo uporabimo, če sta oba leva sinova.
-Levo-levo rotacijo uporabimo, če sta oba sinova desna. Levo-leva rotacija je zrcalna slika desno desne rotacije. 4. Kadar je vozlišče z obravnavanim elementom na nasprotni strani očeta, kot oče glede na svojega očeta uporabimo dvojno rotacijo. Če je vozlišče z obravnavanim elementom desni sin, njegov oče pa levi sin, je to levo-desna rotacija. Če je vozlišče z obravnavanim elementom levi sin, njegov oče pa desni sin, uporabimo desnolevo rotacijo. Ta je zrcalna slika levo-desne rotacije. Operacije Rotacije in lomljenje drevesa so samo pomožne metode, ki jih potrebujemo uspešno izpeljavo pravih operacij, ki so vstavljanje elementa, iskanje elementa v drevesu in brisanje elementa iz drevesa. Vstavljene elementa v drevo Pri vstavljanju elementa v drevo ločimo tri primere:
1)Drevo je prazno element vstavimo v koren drevesa in postopek je končan 2)Če drevo ni prazno in v drevesu ni enakega elementa, kot ga vstavljamo, pridemo do lista drevesa. Takrat naredimo novo vozlišče in ga povežemo v drevo. Nato drevo lomimo in novo vozlišče z elementom, ki ga vstavljamo premaknemo v koren drevesa. 3)Element, ki ga vstavljamo, je enak elementu v drevesu. Zato postopek vstavljanja končamo. Sledi lomljenje drevesa s katerim vozlišče z elementom, ki je enak elementu, ki smo ga želeli vstaviti premaknemo v koren drevesa. Zgled: V prazno lomljeno drevo zaporedno vstavimo elemente: 16, 2, 5, 11, 30, 17, 11 in 22. Vstavimo element 16. Ker vstavljamo v prazno lomljeno drevo, je vozlišče 16 v korenu drevesa in drevo se ne lomi. Vstavimo element 2. Vozlišče z elementom 2 moramo vstaviti v levo poddrevo, ker je 2 < 16. Dobimo: Sledi lomljenje drevesa. Vozlišče 2 ima očeta, ki je koren drevesa in je levi sin, zato uporabimo enojno desno rotacijo. Vstavimo element 5. Ker je 5>2 vstavimo element 5 v desno poddrevo. Naslednja primerjava nam pove, da vozlišče z elementom 5 vstavimo kot levega sina vozlišča z elementom 16 (ker 5< 16 in vozlišče nima levega poddrevesa).
Sledi lomljenje drevesa. Vozlišče z elementom 5 je levi sin, njegov oče pa desni sin, zato uporabimo desno-levo dvojno rotacijo. Opazimo, da se višina drevesa po lomljenju (po rotaciji) zmanjša. Vstavimo element 11. Prva primerjava nam pove, da vozlišče z elementom 11 vstavljamo v desno poddrevo, ker je 11 > 5. Naslednja primerjava nam pove, da vozlišče z elementom 11 vstavimo kot levega sina vozlišča z elementom 16 (ker 11 < 16 in vozlišče nima levega poddrevesa). Sledi lomljenje drevesa. Vozlišče z elementom 11 je levi sin, njegov oče pa desni sin, zato uporabimo desno-levo dvojno rotacijo.
Vstavimo element 30. Prva primerjava nam pove, da vozlišče z elementom 30 vstavljamo v desno poddrevo, ker je 30 > 11. Naslednja primerjava nam pove, da vozlišče z elementom 30 vstavimo kot desnega sina vozlišča z elementom 16 (ker 30 > 16 in vozlišče nima desnega poddrevesa). Sledi lomljenje drevesa. Vozlišče z elementom 30 je desni sin, ravno tako njegov oče, zato uporabimo levo-levo dvojno rotacijo. Vstavimo element 17. Prva primerjava nam pove, da vozlišče z elementom 17 vstavljamo v levo poddrevo, ker je 17 < 30. Naslednja primerjava nam pove, da vozlišče z elementom 17 vstavimo kot desnega sina vozlišča z elementom 65 (ker 17 > 16 in vozlišče nima desnega poddrevesa).
Sledi lomljenje drevesa. Vozlišče z elementom 19 je desni sin, njegov oče pa levi sin, zato uporabimo levo-desno dvojno rotacijo. Vstavimo element 11. Prva primerjava nam pove, da vozlišče z elementom 11 vstavljamo v levo poddrevo, ker je 11 < 17. Naslednja primerjava nam pove, da vozlišče z elementom 11 vstavljamo v levo poddrevo, ker je 11 < 16. Pri naslednji primerjavi ugotovimo, da je vozlišče z elementom 11 že v drevesu, zato tega elementa ne vstavimo in končamo postopek vstavljanja. Čeprav elementa ne vstavimo, pa drevo lomimo. Lomljenje vozlišče z elementom 11 premakne v koren drevesa. Vozlišče z elementom 11 je levi sin, ravno tako njegov oče, zato uporabimo desno-desno dvojno rotacijo. Opazimo, da se višina drevesa po lomljenju (po rotaciji) zmanjša
Vstavimo še zadnji element 22. Prva primerjava nam pove, da vozlišče z elementom 22 vstavljamo v desno poddrevo, ker je 22 > 11. Naslednja primerjava nam pove, da vozlišče z elementom 22 vstavljamo v desno poddrevo, ker je 22 > 16. Tretja primerjava nam pove, da vozlišče z elementom 22 vstavljamo v desno poddrevo, ker je 22 >17. Četrta primerjava nam pove, da vozlišče z elementom 22 vstavimo kot levega sina vozlišča z elementom 30, ker 22 < 30 in vozlišče nima levega poddrevesa.
Iskanje elementa v drevesu Pri iskanju elementa se sprehodimo po drevesu in pri tem v vsakem vozlišču primerjamo vrednost iskanega elementa z vrednostjo elementa v vozlišču drevesa. Pri iskanju elementa v drevesu ločimo tri primere: - Drevo je prazno - V drevesu smo našli vozlišče z iskanim elementom. Z zaporedjem rotacij premaknemo najdeno vozlišče v koren drevesa. -Iskanega elementa ni v drevesu. Z zaporedjem rotacij v koren premaknemo zadnje vozlišče na poti iskanja. Zgled: Dano imamo dvojiško iskalno drevo:
V njem poiščimo element 6. Iskani element je 6. Ker je večji od vrednosti 4 v korenu drevesa, nadaljujemo z iskanjem v desnem poddrevesu. Tu imamo v vozlišču vrednost 7. Ker je element 6 manjši od vrednosti 7, nadaljujemo iskanje v levem poddrevesu. Tu najdemo vrednost 6 in iskanje je končano. Sledi lomljenje drevesa, pri katerem vozlišče z iskano vrednostjo premaknemo v koren drevesa. Vozlišče z iskano vrednostjo je levi sin, njegov oče pa desni sin, zato uporabimo desno-levo dvojno rotacijo. Brisanje elementa iz drevesa Pri brisanju elementa iz drevesa, najprej poiščemo vozlišče z vrednostjo, ki jo želimo brisati iz drevesa. Nato drevo lomimo - z zaporedjem rotacij, vozlišče s tem elementom postane koren drevesa. Nato ta element po določenih postopkih odstranimo iz drevesa. Pri brisanju elementa iz drevesa nastopi ena od treh možnosti: 1. Drevo je prazno. 2. V drevesu pri postopku iskanja elementa najdemo vozlišče z vrednostjo, ki jo želimo brisati iz drevesa in to vozlišče z lomljenjem drevesa premaknemo v koren drevesa. Za brisanje elementa nato ločimo dva primera: a. Če je levo ali desno poddrevo korena prazno, koren izbrišemo in vlogo korena drevesa prevzame njegov (edini) sin. b. Če levo in desno poddrevo korena nista prazna, v levem poddrevesu poiščemo vozlišče z največjo vrednostjo in ga z lomljenjem drevesa postavimo za levega sina korena drevesa (za koren levega poddrevesa korena). V tako preoblikovanem drevesu je koren levega poddrevesa največji element levega poddrevesa in zato nima desnega sina. Za desnega sina mu pripnemo desno poddrevo celotnega drevesa. Nato koren celotnega drevesa (v katerem je element, ki ga želimo brisati) izbrišemo in levo poddrevo postane novo drevo. 3. V drevesu pri postopku iskanja elementa ne najdemo vozlišča z vrednostjo, ki jo želimo brisati iz drevesa, torej tega elementa ni v drevesu. Drevo lomimo tako, da koren postane zadnji element na poti iskanja. Zgled: Dano imamo dvojiško iskalno drevo:
Iz drevesa izbrišimo element 16. Element 16 najprej poiščemo. Ker je večji od vrednosti 5 v korenu drevesa, nadaljujemo z iskanjem v desnem poddrevesu. Tu imamo v vozlišču vrednost 7. Ker je element 16 večji od vrednosti 7, nadaljujemo iskanje v desnem poddrevesu. Tu najdemo vrednost 16 in iskanje je končano. Sledi lomljenje drevesa, pri katerem vozlišče z iskano vrednostjo premaknemo v koren drevesa. Vozlišče z iskano vrednostjo je desni sin, ravno tako njegov oče, zato uporabimo levolevo rotacijo.
Primer: elementi:21,6,30,59,44,17,5,38,27,42,8,2,1,13,3,12,42,55,60,38. Zaporedoma vstavljamo zgornje elemente v iskalno dvojiško drevo in drevo lomimo. Najprej vstavimo 21,nato 6,30,59 in z upoštevanjem, da vstavljamo v iskalno dvojiško drevo in z lomljenjem drevesa dobimo naslednje drevo: Sedaj vstavimo 44. Primerjava 1: 44<59, sledi, da 44 vstavimo v levo poddrevo. Primerjava 2: 44>39, sledi, da 44 vstavimo, kot desnega sina vozlišču 30. Lomimo drevo: zarotiramo enkrat v levo in nato v desno. Dobimo: 44 je sedaj koren dvojiškega drevesa.
Zaporedoma vstavljamo elemente: 17, 5, 38, 27, 42. Dobimo: 42 38 44 27 59 17 30 6 21 5
Vstaviti želimo 8. 8<42, vstavimo v levo poddrevo. 8<38, 8<27, 8<17, 8>6, zato vstavimo kot desnega sina vozlišča 6. Dobimo: Sedaj bomo z levimi in desnimi rotacijami lomili drevo dokler ne bo 8 koren drevesa. Lomimo: 1x v levo in 4x v desno. Dobimo:
Zaporedoma vstavljamo: 2, 1, 13 Dobimo: Vstavimo 3. 3<13, sledi, da vstavimo v levo poddrevo. Ker je 3<6 in manjše od 5 je pa večje od 2 zato 3 vstavimo kot desnega sina vozlišča 2. Lomimo v levo in nato 2x v desno in dobimo:
Po enakem postopku, zaporedoma vstavljamo: 12, 42, 55, 60, 38. Dvojiško drevo z 20 elementi, s korenom 38:
VIRI IN LITERATURA - S. Butalič, Lomljeno drevo, Diplomska naloga, Fakulteta za matematiko in fiziko, 2006, Ljubljana - B. Gril, Lomljena drevesa, Seminarska naloga, Fakulteta za matematiko in fiziko, 2009, Jesenice - http://wiki.fmf.uni-lj.si/wiki/lomljeno_drevo - http://lcm.csa.iisc.ernet.in/dsa/node93.html - http://en.wikipedia.org/wiki/splay_tree