Sanela Buli c Jojki c CRVENO CRNA STABLAmdjumic/uploads/diplomski/JOJ01.pdf · Sanela Buli c Jojki...
Transcript of Sanela Buli c Jojki c CRVENO CRNA STABLAmdjumic/uploads/diplomski/JOJ01.pdf · Sanela Buli c Jojki...
Sveuciliste J. J. Strossmayera u Osijeku
Odjel za matematiku
Sveucilisni nastavnicki studij matematike i informatike
Sanela Bulic Jojkic
CRVENO CRNA STABLADiplomski rad
+
U Osijeku, 2014.
Sveuciliste J. J. Strossmayera u Osijeku
Odjel za matematiku
Sveucilisni nastavnicki studij matematike i informatike
Sanela Bulic Jojkic
Crveno crna stablaDiplomski rad
Mentor: izv. prof. dr. sc. Domagoj Matijevic
U Osijeku, 2014.
Sadrzaj
1 Uvod 1
2 Binarna stabla pretrazivanja 3
2.1 Temeljne definicije . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 Binarna stabla pretrazivanja . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.3 Operacije na binarnim stablima pretrazivanja . . . . . . . . . . . . . . . . . . . 5
2.3.1 Pretrazivanje elemenata . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.3.2 Minimum i maksimum . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.3.3 Prethodnik i sljedbenik . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3.4 Umetanje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3.5 Brisanje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3 Definicija crveno crnog stabla 11
3.1 Osnovna svojstva . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
4 Operacije na crveno crnom stablu 14
4.1 Rotacije . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.2 Umetanje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
4.3 Brisanje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
5 Prosirenje crveno crnih stabala 29
5.1 Stablo statistike reda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
5.2 Intervalna stabla . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
1 Uvod
Neprestanim razvojem racunala i tehnologija, brzina izvodenja operacija sve je veca, dok je cijena
memorije sve niza i niza. Zbog te bi cinjenice netko mogao pomisliti da nema potrebe dalje raditi
na razvoju brzih i efikasnijih algoritama i struktura podataka. No, koliko god racunala bila brza,
nisu beskonacno brza, i koliko god da je memorija jeftina, ipak nije besplatna. S druge strane
pokusaj upravljanja velikim kolicinama podataka moze biti mukotrpan. Da bi to izbjegli, potrebni
su nam dobar algoritam i dobro definirana struktura podataka.
Svrha ovog rada je ukratko prikazati strukturu koju mozemo pronaci u gotovo svakom pro-
gramskom paketu s kojim cemo se susresti u radu s bazama podataka. Trudila sam se da tekst
bude razumljiv i onima koji se jos nisu susreli sa ovom temom. Naglasak sam stavljala na opis
operacija po koracima te prikaz primjera na slikama. Za svaku je operaciju dan i pseudokod
odgovarajuceg algoritma.
Sam pocetak price o stablima nalazimo jos davne 1972. godine. Predstavio ih je Rudolf
Bayer 1 i nazvao simetricnim binarnim B-stablima. Kod tih su struktura operacije pretrazivanja,
umetanja i brisanja imale dobro vrijeme izvrsenja, sve dok se ne bi nasle u situaciji da ih treba
implementirati na ogromnim sortiranim bazama podataka. B-stabla su privukla veliku paznju
i nakon nekolicine pokusaja optimizacije stabala su se pojavile neke varijacije, kao sto su 2-3-
4 stablo i AVL stablo koje su imale ugradene funkcije za samobalansiranje, pa su samim time
olaksali problem sortirane baze podataka. No ni one nisu bile dovoljno dobre.
Tek su 1978 godine Robert Sedgewick 2 i Leonidas Guibas 3 dosli na ideju crveno crnih stabala.
Njih dvojica su pokusali pojednostaviti 2-3-4 stablo i prikazati ga kao binarno stablo a da pri tome
zadrze sve odnose medu elementima 2-3-4 stabla. Kod prvog crveno crnog stabla nisu cvorovi
bili bojani crno ili crveno nego veze medu njima. Crvena veza je spajala elemente iz istog cvora,
a crna veza je bila spoj samih cvorova. Na prvi su pogled ova stabla komplicirana zbog kolicine
svojstava i ogranicavajucih faktora, no uz malo muke moguce je vidjeti genijalnost koja se krije
u ovoj ideji.
Cesto se postavljalo pitanje zasto je odabrana bas crvena boja? Zbog izgleda. U to vrijeme
je autorima bio dostupan laserski pisac Xerox PARC na kojemu je najljepsi ispis bio upravo u
crvenoj boji.
Tajna samobalansirajuceg procesa kod crveno crnih stabala je upravo u bojama cvorova. Svaki
puta kada umecemo ili brisemo cvorove iz stabla, mijenjamo njegovu strukturu. Ta promjena
strukture moze uzrokovati prekrsaj nekog od svojstava stabla. Tada pomocu funkcija rotacije i
promjena boje vracamo narusena svojstva. Kada umecemo crveni cvor, ne mora nuzno doci do
prekrsaja. Ako i dode, popravak stabla traje relativno kratko i ne zauzima puno prostora. Upravo
zbog toga su crveno crna stabla jedna od glavnih struktura koje danas koristimo i zasluzuju da
svatko tko se zeli baviti informatikom zna barem osnove o njima.
Velika vecina ovoga rada je utemeljena upravo na [1]. Iz te su knjige preuzeti i svi algoritmi
koji se ovdje mogu naci. Sam rad je podijeljen na tri glavna dijela; prvi dio govori o binarnim
1Rudolf Bayer (1939 - ), njemacki informaticar2Robert Sedgewick (1946- ), americki informaticar3Leonidas Guibas, americki informaticar, profesor na Stanfordu
1
stablima, drugi dio o crveno crnim stablima i posljednji dio o prosirenju crveno crnih stabala.
U Poglavlju 2. je dan pregled svih temeljnih definicija vezanih za stabla, pri cemu su sve
definicije ilustrirane primjerom. Malo je veci naglasak na ovaj dio jer su same operacije razumljivije
dok se ne umjesa boja cvorova. Svaka operacija je potkrepljena primjerom, tako da se i vizualno
moze dozivjeti sama situacija.
U Poglavlju 3. je dana definicija i opis osnovnih svojstava crveno-crnih stabala. Ovdje se
govori samo o gradi crveno crnih stabala. Objasnjena su svojstva i temeljne karakteristike vezane
iskljucivo za ovu vrstu stabala.
U Poglavlju 4. su obradene operacije na crveno crnim stablima. Sve operacije koje izvodimo
na binarnim stablima pretrazivanja, izvodimo i na crveno crnim stablima. Procedure su jednake,
pa u ovome dijelu nisu detaljno opisane. Tu je naglasak na popravljanje svojstava stabla ukoliko
dode do prekrsaja. Operacija umetanja cvora je detaljno ilustrirana primjerom. Kod operacije
brisanja, dane su samo pocetne i zavrsne slike umjesto cijelog procesa, zbog velikog broja mogucih
slucaja.
Na samom kraju, u Poglavlju 5. je opisan nacin prosirenja crveno-crnih stabala. Iako se
ovdje ne govori konkretno o bojama cvorova, vec o samim svojstvima pojedine strukture, treba
imati na umu da je temeljna struktura ipak crveno crno stablo.
2
2 Binarna stabla pretrazivanja
2.1 Temeljne definicije
Kada govorimo o stablima, mislimo na strukturu podataka koja graficki prikazuje hijerarhiju medu
elementima. Osnovna gradevna jedinica stabla je cvor. U svakom cvoru je pohranjen podatkovni
element kojeg cemo nazivati kljucem, key[x]. Takoder svaki cvor sadrzi pokazivace na cvorove
koji su direktno spojeni s njim. Cvorovi y1, ..., yn koji su spojeni s istim cvorom x se nazivaju
djecom cvora x, pri cemu je x njihov roditelj. Cvorovi y1, ..., yn se medusobno nazivaju bracom.
Cvor koji nema roditelja nazivamo korijenom, a cvor koji nema djece nazivamo listom. Svaki cvor
koji nije list je korijen podstabla koje se sastoji od njegove djece, unuka, praunuka itd.
Dani u tjednu
Radni dani Neradni dani
Pon Uto Sri Cet Pet Sub Ned
Slika 1. Prikaz stablaste strukture.
U primjeru na slici, ”Dani u tjednu” je korijen stabla. ”Radni dani” i ”Neradni dani” su
njegova djeca. ”Radni dani” je korijen podstabla s cvorovima ”Pon”, ”Uto”, ”Sri”, ”Cet” i
”Pet”. Ti cvorovi nemaju djece pa su ujedno i listovi ovog stabla.
Jedno od temeljnih obiljezja svakog stabla je i njegova visina. Visinu stabla definiramo kao
broj cvorova na najduzem putu od korijena do lista. U primjeru na gornjoj slici, visina stabla je
3 jer imamo tri cvora na najduzoj putanji (npr. Dani u tjednu - Radni dani - Pet).
2.2 Binarna stabla pretrazivanja
Binarno stablo pretrazivanje (BST) je dinamicka struktura podataka4 kojoj je glavno svojstvo da
svaki cvor moze imati najvise dva djeteta. Pri tome roditelj i djeca medusobno zadovoljavaju
BST svojstvo:
Kljuc lijevog djeteta cvora x mora biti ≤ od kljuca cvora x. Isto vrijedi i za desno dijete, kljuc
desnog djeteta mora biti ≥ od kljuca cvora x.
BST mozemo prikazati kao povezanu listu u kojoj svaki cvor ima tri polja; pokazivace na lijevo
dijete, desno dijete i roditelja. Prilikom kreiranja povezane liste bitno nam je na koji cemo nacin
obilaziti stablo. Razlikujemo tri vrste obilaska stabla PREORDER, INORDER i POSTORDER
obilazak.
Kod INORDER obilaska stabla, korijen obilazimo izmedu lijevog i desnog podstabla.
4struktura podataka kojoj je velicina ogranicena jedino kolicinom slobodne memorije operacijskog sustava.
3
Algorithm INORDER-TREE-WALK(x)
1. if x 6= NIL
2. then INORDER− TREE −WALK(left[x])
3. print key[x]
4. INORDER− TREE −WALK(right[x])
30
20 55
95
75
71
40
4936
15
9 17 23
27
29Slika 2. BST stablo.
Na primjeru sa gornje slike Inorder obilazak bi izgledao ovako: 9, 15, 17, 20, 23, 27, 29, 30,
36, 40, 49, 55, 71, 75, 95.
Kod PREORDER obilaska stabla obilazimo korijen prije podstabala.
Algorithm PREORDER-TREE-WALK(x)
1. if x 6= NIL
2. then print key[x]
3. PREORDER− TREE −WALK(left[x])
4. PREORDER− TREE −WALK(right[x])
Na primjeru sa gornje slike, Preorder obilazak bi izgledao ovako: 30, 20, 15, 9, 17, 27, 23,
29, 55, 40, 36, 49, 75, 71, 95.
I na kraju, kod POSTORDER obilaska stabla korijen obilazimo nakon podstabala.
Algorithm POSTORDER-TREE-WALK(x)
1. if x 6= NIL
2. then POSTORDER− TREE −WALK(left[x])
3. PREORDER− TREE −WALK(right[x])
4. print key[x]
Na primjeru sa slike, Postorder bi izgledao ovako: 9, 17, 15, 23, 29, 27, 20, 36, 49, 40, 71,
95, 75, 55, 30.
4
2.3 Operacije na binarnim stablima pretrazivanja
2.3.1 Pretrazivanje elemenata
Najcesce koristena operacija na binarnim stablima pretrazivanja je upravo trazenje danog elementa
medu elementima u stablu.
Pretragu uvijek krecemo od korijena stabla. Ako korijen ima kljuc koji trazimo, potraga je gotova.
U suprotnom vrsimo usporedbu kljuceva. Ako je kljuc trazenog elementa strogo manji od kljuca
korijena, potragu nastavljamo u lijevom podstablu. Ako je kljuc trazenog elementa strogo veci
od kljuca korijena, tada potragu nastavljamo u desnom podstablu.
Algorithm BST-Search(x,k)
1. y ← x
2. while y 6= NIL
3. do if key[y] = k
4. then return y
5. else if key[y] < k
6. then y ← right[y]
7. return (”NOT FOUND”)
30
20 55
95
75
71
40
4936
15
9 17 23
27
29
71 > 30pretragu nastavljamou desnom podstablu
71 > 55nastavljamo u desnompodstablu
71 < 75nastavljamo u li-jevom podstablu
pronasli smocvor i zaustavl-jamo pretragu
BST-Search(x,71)
Slika 3. Primjer pretrage elementa u BST stablu.
Buduci da prilikom pretrage elementa prolazimo jednom granom stabla najvise do dubine lista,
vrijeme izvrsenja operacije je proporcionalno visini stabla, dakle O(h).
2.3.2 Minimum i maksimum
Uz operaciju pronalazenja elemenata, cesto nas zanima i koji su najmanji i najveci element u
stablu. Za to nam sluze sljedece dvije operacije: BST-Minimum i BST-Maximum.
Kako bi pronasli najmanji element u stablu, krecemo od korijena i pratimo pokazivace prema
lijevom djetetu. Trazeni cvor je najljeviji cvor u stablu koji nema lijevo dijete.
5
Algorithm BST-Minimum(x)
1. if x = NIL
2. then return (”Empty tree.”)
3. y ← x
4. while left[y] 6= NIL
5. do y ← left[y]
6. return key(y)
Slicno vrijedi i za pronalazenje maksimalnog elementa, samo pratimo pokazivace na desno
dijete.
Algorithm BST-Maximum(x)
1. if x = NIL
2. then return (”Empty tree.”)
3. y ← x
4. while right[y] 6= NIL
5. do y ← right[y]
6. return key(y)
Vrijeme izvrsenja ovih operacija je propocionalno sa visinom stabla, O(h).
2.3.3 Prethodnik i sljedbenik
Prethodnik nekog elementa x je maksimalni element u njegovom lijevom podstablu. Slicno vrijedi
i za sljedbenik; sljedbenik elementa x je minimalni element desnog podstabla tog cvora. Direktan
dokaz ovih tvrdnji proizlazi iz INORDER obilaska stabla.
Algorithm TREE-SUCCESSOR(x)
1. if right[x] 6= NIL
2. then return TREE −MINIMUM(right[x])
3. y ← p[x]
4. while y 6= NIL and x = right[y]
5. do x← y
6. y ← p[y]
7. return y
2.3.4 Umetanje
Za razliku od do sada navedenih operacija, ova operacija uzrokuje promjene na stablu.
Operaciju umetanja mozemo podijeliti u dvije faze:
• Pronalazenje mjesta gdje cemo umetnuti novi cvor.
• Umetanje novog cvora.
6
Novi cvor uvijek umecemo na mjesto lista. Prema tome, prvo moramo naci odgovarajuci list
na cije mjesto cemo umetnuti novi cvor. To radimo tako da provjeravamo pokazivace na lijevo
ili desno dijete u ovisnosti o usporedbi kljuceva cvora kojeg zelimo umetnuti i cvora na kojem
se trenutno nalazimo. Kada dodemo do cvora koji ima pokazivac na NIL dijete, mijenjamo mu
pokazivac sa NIL cvora na novi cvor. Novom cvoru postavljamo pokazivace za djecu na NIL
cvorove.
Algorithm TREE-INSERT(T,x)
1. y ← NIL
2. x← root[T ]
3. while x 6= NIL
4. do y ← x
5. if key[z] < key[x]
6. then x← left[x]
7. else x← right[x]
8. p[z]← y
9. if y = NIL
10. then root[T ]← z
11. else if key[z] < key[y]
12. then left[y]← z
13. else right[y]← z
30
20 55
95
75
71
40
4936
15
9 17 23
27
29
TREE-INSERT(T, 73)
73
73 > 30→
73 > 55→73 < 75←
73 > 71→
Slika 4. Umetanje elementa s kljucem 73 u stablo.
I ova operacije se izvrsava u O(h) vremenu.
7
2.3.5 Brisanje
Za razliku od do sada navedenih operacija na binarnom stablu pretrazivanja, ova operacija je
malo slozenija. Dva su glavna dijela ove procedure; pronalazak cvora koji trebamo obrisati te
brisanje elementa. Sama procedura brisanja ovisi o polozaju elementa u stablu, odnosno koliko
taj element ima djece. Razlikujemo tri slucaja:
• Trazeni cvor nema djece.
• Trazeni cvor ima jedno dijete.
• Trazeni cvor ima dva djeteta.
Slucaj kada cvor nema djece je trivijalan. Pokazivac roditelja cvora kojeg trebamo obrisati
samo preusmjerimo na NIL cvor.
10
5
3 7
6
11
14
13
TREE-DELETE(T, 13)
Slika 5. Brisanje cvora koji nema djece.
U slucaju kada cvor koji treba obrisati ima jedno dijete imamo situaciju slicnu prethodnoj.
Ovdje pokazivac sa roditelja na trazeni cvor preusmjeravamo na dijete trazenog cvora, a trazeni
cvor izrezemo.
10
5
3 7
6
11
14
13
TREE-DELETE(T, 14)
8
10
5
3 7
6
11
13
Slika 6. Brisanje cvora s jednim djetetom.
Kada cvor koji trebamo obrisati ima dva djeteta, imamo malo vise posla. Kada bi kao u
prethodnim slucajevima samo izrezali cvor, podijelili bi stablo na dva podstabla. Rjesenje nalazimo
u zamjeni elemenata: mijenjamo mjesta cvoru koji zelimo izbrisati i maksimalnom elementu lijevog
podstabla tog cvora. Nakon zamjene ce trazeni cvor imati najvise jedno dijete pa imamo situaciju
kao u prethodnim slucajevima.
10
5
3 7
6
11
14
13
TREE-DELETE(T, 10)
7
5
3 10
6
11
13
Slika 7. Brisanje cvora sa dva djeteta.
9
Posljednji slucaj mozemo rijesiti i na simetrican nacin zamjenom cvora kojeg zelimo obrisati i
minimalnog elementa u desnom podstablu.
Algorithm TREE-DELETE(T,z)
1. if left[z] = NIL or right[z] = NIL
2. then y ← z
3. else y ← TREE − SUCCESSOR(z)
4. if left[y] 6= NIL
5. then x← left[y]
6. else x← right[y]
7. if x 6= NIL
8. then p[x]← p[y]
9. if p[y] = NIL
10. then root[T ]← x
11. else if y = left[p[y]]
12. then left[p[y]]← x
13. else right[p[y]]← x
14. if y 6= z
15. then key[z]← key[y]
16. copy y’s data into z
17. return y
10
3 Definicija crveno crnog stabla
Iako je vrijeme izvrsenja operacija na binarnim stablima pretrazivanja relativno dobro, nemamo
uvijek mogucnost kontrolirati redoslijed unosa podataka, sto moze uvelike produziti vrijeme
izvrsenja operacija. Tu nam mogu pomoci stabla koja imaju ugradene funkcije za balansira-
nje. Takva stabla nazivamo samobalansirajucim stablima. Medu njih ubrajamo i 2-3-4 stabla,
AVL stabla te crveno-crna stabla.
3.1 Osnovna svojstva
Crveno crno stablo je tip samobalansirajuceg stabla koje zadovoljava sljedeca svojstva:
1. Svaki cvor je ili crn ili crven
2. Korijen je crn
3. Listovi su crni
4. Niti jedan crveni cvor ne smije imati crveno dijete (Krsenje ovog svojstva se naziva crvenim
prekrsajem)
5. Svaki jednostavan put od korijena do lista ima jednak broj crnih listova.
Iz ovih svojstava proizlaze neke cinjenice:
• Niti jedan cvor ne moze imati samo jedno crno dijete.
• Crveni cvor ili nema djece ili ima dva crna djeteta.
• Crni cvor moze imati bilo koju kombinaciju djece osim jednog crnog djeteta.
3
2
1Slika 8. Primjer binarnog stabla koje nije crveno crno stablo..
Listovi crveno crnog stabla nemaju vrijednosti, tj. tretiraju se kao NIL vrijednosti. Zbog
jednostavnosti prilikom programiranja, i zbog ustede memorije, svi NIL cvorovi se mogu zamijeniti
jedinstvenim zamjenskim cvorom.
Buduci da je prema svojstvu 5 broj crnih cvorova na svakom putu jednak, mozemo uvesti
velicinu koju cemo nazvati crnom visinom stabla i oznaciti sa bh(x) gdje je x korijen stabla. Pri
tome treba naglasiti da sam x nije ukljucen u zbroj. Na slici je dan primjer crne visine za svaki
cvor.
11
bh=2
bh=2 bh=2
bh=1 bh=1 bh=1 bh=1
bh=0 bh=0 bh=0 bh=0 bh=0 bh=0 bh=0
bh=1
bh=0 bh=0
Slika 9. Primjer crne visine po cvorovima.
Teorem 3.1 Bilo koje crveno crno stablo korijena x, ima najmanje n = 2bh(x) − 1 unutarnjih
cvorova, gdje je bh(x) crna visina cvora x.
Dokaz. Dokaz provodimo matematickom indukcijom za visinu x-a. Ako je x− a = 0, onda
je x list stabla, tj. x je NIL[T]. Tada x sadrzi 2bh(x) − 1 = 20 − 1 = 0 unutarnjih cvorova. Za
pretpostavku smatrajmo da je x unutarnji cvor sa dva djeteta. Svako dijete ima visinu bh(x) ili
bh(x)−1, ovisno o tome je li crno ili crveno. Kako je visina djeteta od x manja od same vrijednosti
od x, primjenom pretpostavke zakljucujemo da svako dijete ima barem 2bh(x) − 1 unutarnjih
cvorova. Prema tome svako podstablo korijena x ima (2bh(x)−1−1)+(2bh(x)−1−1)+1 = 2bh(x)−1
unutarnjih cvorova.
Teorem 3.2 Barem pola cvorova na nekom putu u crveno crnom stablu mora biti crno.
Dokaz. Prema svojstvu 4, ukoliko postoji crveni cvor u stablu, uz njega mora ici odgovarajuci
crni cvor. U najgorem slucaju, crveni i crni cvorovi ce alterirati pa ce ih biti jednako mnogo.
Teorem 3.3 U crveno crnom stablu niti jedan put od nekog cvora do lista iz njegovog podstabla
nije vise od dva puta duzi od bilo kojeg drugog puta iz istog cvora.
Dokaz. Prema definiciji, svaki put od cvora do lista sadrzi jednak broj crnih cvorova. Prema
teoremu 3.2, barem je polovina cvorova na takvom putu crna. Prema tome ne moze biti vise
nego duplo cvorova na jednom putu u odnosu na druge. Stoga niti jedna putanja nije vise od
dvostruko dulja od bilo koje druge.
12
Teorem 3.4 Crveno crno stablo sa n unutarnjih cvorova ima visinu od h ≤ 2log(n + 1)
Dokaz. Neka je h visina stabla korijena x. Prema teoremu 3.1, n ≥ 2h2 − 1. Iz toga slijedi,
n ≥ 2h2 − 1 (1)
n + 1 ≥ 2h2 (2)
lg(n + 1) ≥ h
2(3)
2lg(n + 1) ≥ h (4)
13
4 Operacije na crveno crnom stablu
Crveno crno stablo, kao i binarno stablo pretrazivanja podrzava operacije MINIMUM, MAXI-
MUM, PRETHODNIK, SLJEDBENIK i PRETRAZIVANJE, i izvodi ih u O(h) vremenu, gdje je
h visina stabla. Te operacije prilikom izvodenja ne mijenjaju stablo. S druge strane, operacije
umetanja i brisanja prilikom izvodenja mijenjaju strukturu stabla, i pri tome ponekad prekrse
pravila crveno crnog stabla. Iz tog razloga je cesto potrebno napraviti neke promjene kako bi se
ponovo uspostavila struktura stabla koja zadovoljava dana svojstva. Primjeri takvih promjena su
promjena boja cvorova i preusmjeravanje pokazivaca (rotacije).
4.1 Rotacije
Rotacije su osnovna operacija za popravljanje strukture stabla, i to ne samo crveno crnog stabla
vec bilo kojeg binarnog stabla buduci da nisu vezane za boje cvorova. Vecina samobalansirajucih
struktura koristi rotacije kao dio samobalansirajuceg procesa. Dvije su vrste rotacija, u lijevo i u
desno.
Prilikom upotrebe lijeve rotacije, pretpostavljamo da desno dijete promatranog cvora nije NIL.
Ako je x promatrani cvor, a y njegovo desno dijete, tada se rotacija u lijevo odvija oko veze x-y,
na nacin da tada y postaje korijen, x postaje lijevo dijete od y, a lijevo dijete od y postaje desno
dijete od x.
Kod desne rotacije imamo obrnutu stvar. Neka je sada y promatrani cvor a x njegovo lijevo
dijete, tada rotacijom u desno x postaje roditelj, y desno dijete od x, a desno dijete od x postaje
lijevo dijete od y.
A
B C A B
C
ROTACIJA U DESNO
ROTACIJA U LIJEVO
Slika 10. Rotacija na binarnom stablu.
Lako je uociti da su rotacija u lijevo i rotacija u desno inverzne operacije, pa su im i algoritmi
simetricni. U nastavku je dan algoritam za rotaciju u lijevo. Algoritam za rotaciju u desno se
dobije jednostavnom supstitucijom lijevo⇔ desno.
Algorithm Rotacija u lijevo
1. y ← desno[x]
2. right[x]← left[y]
3. if left]y] = NIL
4. then p[left[y]]← x
5. p[y]← p[x]
6. if p[x] = NIL
14
7. then root[T ]← y
8. else if x = left[p[x]]
9. then left[p[x]]← y
10. else right[p[x]]← y
11. left[y] ←x
12. p[x]← y
Vazno je naglasiti da A, B i C predstavljaju podstabla s korijenima u tim cvorovima. Kada se
A, B i C pomaknu, svi njegovi potomci se pomicu zajedno s njima.
Rotacije su korisne iz tri razloga:
1. Cuvaju svojstva binarnog stabla. Jedan od nacina provjere te tvrdnje je da uocimo da je
redoslijed cvorova s lijeva na desno jednak u oba slucaja.
2. Izvrsavaju se u konstantnom vremenu jer mijenjamo pokazivace kod samo cetiri cvora:
zelenog, plavog, roditelja gornjeg cvora te cvora B.
3. Mogu se koristiti za prilagodbu visina podstabala unutar binarnog stabla.
15
4.2 Umetanje
Kako bi umetnuli cvor, prvo moramo pronaci odgovarajuce mjesto u stablu. Procedura je jednaka
kao kod binarnog stabla pretrazivanja, usporedujemo kljuceve cvorova i pomocu usporedbe putu-
jemo po stablu dok ne dodemo do odgovarajuceg NIL cvora. Umjesto NIL cvora, umecemo zeljeni
cvor, a njemu pridruzujemo dva NIL cvora umjesto djece. Nakon umetanja, cvoru pridruzujemo
crvenu boju. Zatim se provjerava roditelj novoga cvora, kako bi utvrdili je li doslo do krsenja
nekog od svojstava. Postavlja se pitanje koje svojstvo moze biti prekrseno?
• Svaki cvor je ili crn ili crven - uvijek vrijedi jer je i novom cvoru dodijeljena boja.
• Korijen i listovi su crni - moze doci do krsenja ukoliko je stablo prazno prije umetanja, pa
novi cvor postaje korijen.
• Djeca crvenog cvora ne smiju biti crvena - to moze biti prekrseno ukoliko je roditelj novog
cvora crven.
• Broj crnih cvorova na svakom putu ostaje isti jer umecemo crveni cvor.
Ukoliko dode do prekrsaja, potrebno je pozvati proceduru za popravak kao bi se uspostavila
struktura stabla. Taj proces ili vraca sva crveno crna svojstva, ili problematicnu situaciju pomice
gore uz stablo. To se odvija u konstantnom vremenu. Nakon toga rekurzijom vracamo svojstva
u log vremenu.
Promotrimo situaciju na kojoj provodimo rekurziju. Dano nam je crveno crno stablo T, te
cvor x u tom stablu. T zadovoljava sva crveno crna svojstva osim da x moze biti korijen ili da
mu je roditelj crven.
Osnovni slucaj gdje je x korijen je jednostavan. Obojimo x crno i gotovi smo. To dodaje
tocno jedan cvor svim korijen-NIL putanjama, postivajuci svojstvo 5. Korijen je sada crn, pa je
zadovoljeno i prvo svojstvo.
Prepostavimo sada da x nije korijen. Tada x ima roditelja. Pretpostavimo, nadalje, da je
x − ov roditelj crven, jer u suprotnom nemamo sto popravljati. Tada p ne moze biti korijen jer
nije crn. To znaci da postoji i djed g. Buduci da je p crven, g mora biti crn jer pretpostavljamo
da T sadrzi samo jedan crveni par (dva crvena cvora u nizu). Dakle, nasa situacija je:
• x je crven
• x ima roditelja p koji je crven
• p ima roditelja g koji je crn
Razmatramo dva slucaja:
1. x ima crvenog ujaka u (u je brat x-ovog roditelja p)
2. x nema ujaka ili mu je ujak crn
16
SLUCAJ 1: x ima crvenog ujaka. U ovom slucaju prvo obojamo g crveno, te p i u u
crno. Ako g ima crnog roditelja, gotovi smo. Ako g ima crvenog roditelja, rekurziramo po g.
Ako je g korijen, jednostavno ga obojamo u crno kako bi zadovoljili sva svojstva. U ovom slucaju
nije bitno koji cvorovi imaju koju bracu, ili sa koje su strane x ili p. Ako imamo crvenog ujaka,
mozemo promijeniti boju i rekurzirati po cvoru koji je dvije razine iznad. U tom slucaju mozemo
provesti bilo koju rotaciju.
g
p
x
u
p
g
u
x
Nakon umetanja
Nakon popravljanja
Slika 11. Slucaj 1.
SLUCAJ 2: x nema ujaka ili mu je ujak crn. U ovom slucaju rotiramo g desno, obojamo
ga crveno i promijenimo boju promoviranom cvoru p u crno. I tada smo gotovi, rekurzija nije
potrebna. Nije bitno ima li x brata ili ne, ali da ga ima, brat y bi morao biti crn, jer vec imamo
jedan crveni par.
g
p
x
u
p
gx
Nakon umetanja
Nakon popravljanja
y
y u
Slika 12. Slucaj 2.
17
Da je p desno dijete od g, a x desno dijete od p, slijedili bi isti pristup kao i gore, jedino sto
bi umjesto desne provodili lijevu rotaciju. Jedinu poteskocu u ovom slucaju mozemo naci ako x i
p leze na suprotnim stranama njihovih roditelja. Kada dode do toga, rotiramo p na odgovarajcu
stranu roditelja, kako bi dobili neki vec poznati slucaj gdje su oboje na istoj strani. Ovo smatramo
pretkorakom za Slucaj 2.
Na primjer, pretpostavimo da je x desno dijete od p, a p lijevo dijete od g. Kada do toga
dode, prvo rotiramo p ulijevo bez promjena boja cvorova. To ce postaviti x iznad p a ispod y.
Zatim pozivamo proceduru popravka na p.
g
p u
g
ux
Nakon umetanja
Nakon popravljanja
x
p
Slika 13. Slucaj 2 - simetricna situacija.
Ova rotacija ima tri ucinka:
1. Podstablo s korijenom u p-ovom lijevom djetetu, ako ga ima, dobiva x kao novog prethod-
nika, koji je crven.
2. Podstablo s korijenom u x-ovom desnom djetetu, ako postoji, ima jednog pretka manje p,
ali je p crven.
3. Podstablo s korijenom u x-ovom lijevom djetetu, ako postoji, se pomice tako da postaje
p-ovo desno podstablo, ali i dalje ima dva crvena cvora direktno iznad.
U svakom slucaju, nismo mijenjali broj crnih cvorova na bilo kojoj putanji i nismo uveli nijedan
novi crveni par. Stoga je ova operacija sigurna za upotrebu jer ne dovodi do novih prekrsaja.
Nadalje, pretkorak provodimo samo jednom, buduci da je potreban samo za slucaj 2, do kojeg
dolazi najvise jednom.
Slicno, ako je x bio lijevo dijete od p i p je desno dijete od g, tada rotiramo p u desno i
pozivamo proceduru popravka na p.
Tri su stvari bitne za ovaj proces:
1. Imat cemo najvise dvije rotacije tokom cijelog procesa. To je stoga sto imamo rekurziju
samo u slucaju 1 koji ne koristi ni jednu rotaciju, a u slucaju 2 imamo najvise dvije rotacije.
18
2. Ovaj proces koristi samo konstantnu memoriju, jer je jedini rekurzivni poziv na samom
kraju.
3. Proces ce biti vrlo brz. Rekurzivni korak je u konstantnom vremenu, pa ce popravka biti
logaritmicna. Usprkos tome, cijeli proces se svodi na promjene boje nekih cvorova i mozda
dvije rotacije.
Kako bi umetnuli novi cvor, pozivamo sljedecu funkciju.
Algorithm RB-INSERT(T,z)
1. y ← nil[T ]
2. x← root[T ]
3. while x 6= nil[T ]
4. do y ← x
5. if key[z] < key[x]
6. then x← left[x]
7. else x← right[x]
8. p[z]← y
9. if y = nil[T ]
10. then root[T ]← z
11. else if key[z] < key[y]
12. then left[y]← z
13. else right[y]← z
14. left[z]← nil[T ]
15. right[z]← nil[T ]
16. color[z]← RED
17. RB-INSERT-FIXUP(T,z)
Nakon sto smo umetnuli novi cvor, poziva se funkcija RB-INSERT-FIXUP(T,z) koja ce pro-
vjeriti je li doslo do nekog prekrsaja, te koja ce popraviti prekrsaj ukoliko je doslo do njega.
Algorithm RB-INSERT-FIXUP(T,z)
1. while color[p[z]] = RED
2. do if p[z] = left[p[p[z]]]
3. then y ← right[p[p[z]]]
4. if color[y] = RED
5. then color[p[z]]← BLACK
6. color[y]← BLACK
7. color[p[p[z]]]← RED
8. z ← p[p[z]] i
9. else if z = right[p[z]]
10. then z ← p[p[z]]
11. LEFT-ROTATE(T,z)
19
12. color[p[z]]← BLACK
13. color[p[p[z]]]← RED
14. RIGHT-ROTATE(T, p[p[z]]])
15. else y ← left[p[p[z]]]
16. if color[y] = RED
17. then color[p[z]]← BLACK
18. color[y]← BLACK
19. color[p[p[z]]]← RED
20. z ← p[p[z]]
31
15 48
2 20 41 50
7 35 45
36
36 > 31 idemo u desno podstablo od 31
31
15 48
2 20 41 50
7 35 45
36
36 < 48 pa prelazimo na lijevo podstablo od 48
20
31
15 48
2 20 41 50
7 35 45
36
36 < 41 pa prelazimo na lijevo podstablo od 41
31
15 48
2 20 41 50
7 35 45
36
36 > 35 pa opet idemo desno. Buduci da 35 nema djece, novi cvor postaje njegovo desno dijete.
31
15 48
2 20 41 50
7 35 45
36
Kako je 35 crven, doslo je do crvenog prekrsaja. Tu imamo Slucaj 2 - ”x-ov ujak je crven”.
21
31
15 48
2 20 41 50
7 35 45
36
Posto smo crveni prekrsaj pomakli uz stablo, ponovo imamo Slucaj 2 te provodimo isti
postupak.
31
15 48
2 20 41 50
7 35 45
36
Na kraju nam ostaje crveni korijen kojeg jednostavno bojamo u crno, bez novih prekrsaja.
Slika 14.Primjer umetanja cvora u stablo.
22
4.3 Brisanje
Proces brisanja nekog cvora zapocinjemo tako da prvo pronademo u stablu cvor koji treba izbrisati.
Ako je cvor list, samo ga izrezemo iz stabla. Ako cvor ima jedno dijete, izbacimo cvor, zamijenimo
ga njegovim sljedbenikom, te obrisemo cvor koji je njegov sljedbenik zauzimao. U svim slucajevima
brisemo cvor sa najvise jednim djetetom.
Razlikujemo ”cvor koji treba obrisati” i ”obrisani cvor”. Ako cvor koji zelimo obrisati ima
najvise jedno dijete, tada se oba pojma odnose na isto. Ako ima dva djeteta tada je ”obrisani
cvor” zapravo sljedbenik ”cvora koji trebamo obrisati”, a sljedbenik ima samo jedno dijete. To
dijete ce zamijeniti izbrisani cvor, te ako dode do krsenja nekog pravila, doci ce upravo na tom
mjestu. Rekurzivna procedura tu pocinje.
Sto ako obrisani cvor nema djece? U tom slucaju odabiremo jedan od NIL pokazivaca, te
zapocinjemo rekurziju na tom NIL cvoru. To nam je dozvoljeno jer procedura popravljanja ne
promovira cvor uz stablo. Rekurziji je samo potrebno mjesto pocetka.
Neka je x dijete obrisanog cvora. Procedura popravka pocinje u x, te x trenutno zauzima
mjesto u stablu koje je obrisani cvor nekada zauzimao. Pogledajmo neke rubne slucajeve.
Ako je obrisani cvor bio crven, nemamo sta popravljati. Obrisani cvor nije mogao biti korijen,
stoga korijen ostaje crn, te sve putanje i dalje sadrze jednak broj crnih cvorova. U tom slucaju,
procedura popravka vraca stablo koje je vec crveno-crno.
Nadalje, pretpostavimo da je obrisani cvor bio crn. Ako je obrisani cvor bio korijen, to je
jednostavno. Sad je stablo prazno, a prazno stablo je valjano crveno-crno stablo. Ili je x stvarni
cvor i postaje novi korijen. Ako je x crven, obojamo ga u crno i gotovi smo. Ako je x crn,
nemamo sta popravljati. Pretpostavimo da x nije korijen. Trenutno imamo sljedecu situaciju.
Upravo smo obrisali crni cvor iz valjanog crveno-crnog stabla i zamijenili ga s x. Buduci da x nije
korijen, ima roditelja p. Takoder, buduci da x mijenja crni cvor, mora imati brata y. To je zato
sto ni jedan cvor ne moze imati samo jedno dijete. To bi bio prekrsaj cetvrtog svojstva.
U nasem stablu sad fali crni cvor u x, i to je jedini prekrsaj crveno-crnih svojstava. Tada
kazemo da stablu fali crno u x. Drugi naziv za ovu situaciju je dvostruki crni cvor.
Rekurzivna procedura popravljanja zapocinje u tom dvostruko crnom cvoru. Nije nam bitno
koliko djece x ima, samo smo morali obrisati cvor koji ima najvise jedno dijete kako bi dobili x i
zapoceli rekurziju.
Evo tocne situacije za rekurziju:
Imamo crveno-crno stablo u kojemu su zadovoljena sva crveno-crna svojstva, osim da moze
postojati i cvor x, dvostruko crn, takav da svi putevi od korijena do lista kroz x imaju jedan
crni cvor manje, u odnosu na putanje koje ne prolaze kroz x. Nasa strategija je upotrijebiti
konstantan broj rotacija i promjena boje kako bi odmah povratili sva svojstva ili kako bi dupli
crni cvor pomaknuli uz stablo bez novih prekrsaja. Buduci da se rotacije i bojanja izvode u
konstantnom vremenu, rekurzivni korak ce se izvrsiti u konstantnom vremenu. Pa je prema tome
i cijela procedura popravljanja izvedena u O(logn) vremenu.
Ako dvostruki crni cvor ikad dode u crveni cvor, odmah smo u mogucnosti popraviti svojstvo
4 - jednostavno obojamo crveni cvor u crno.
Temeljno postoje tri slucaja. Dva su konacna, a jedan rekurzivan. Medutim, ovi konacni
23
slucajevi mogu ponekad zahtjevati i pretkorake, pa zajedno s njima imamo pet slucaja.
To su:
1. x-ov brat y je crven
2. x-ov roditelj p je crven, y je crn, te y ima dvoje crne djece ili nema niti jedno dijete
3. p je crn, y je crn, i y ima dva crna djeteta ili nema djece
4. y je crn, desno dijete mu je crno, lijevo je crveno
5. y je crn, desno dijete od y je crveno
Ako boja cvora nije odredena opisom slucaja, tada njegova boja nije bitna za argument.
Moze biti i crn i crven. Takvi cvorovi ce na slikama biti oznaceni bijelo, dok ce dvostruki crni biti
oznaceni s dvostrukim obrubom.
U prvom slucaju y mora imati dva crna djeteta jer je crveni brat crnog cvora i pretpostavljamo
da je dvostruki crni cvor jedini prekrsaj u stablu. Slucajevi 2 i 5 su konacni slucajevi. Slucaj 3
je jedini rekurzivni slucaj. Slucaj 4 je pretkorak za slucaj 5. Slucaj 1 je pretkorak koji direktno
dovodi do zavrsetka preko slucaja 2, 4 ili 5. Slucajevi 1, 2, 4 i 5 se izvode najvise jednom za
vrijeme popravka. Na primjerima cemo pokazati da samo slucajevi 1, 4 i 5 izvode rotacije. Iz
toga slijedi da se tokom cijelog procesa izvode najvise tri rotacije.
U primjerima za slucajeve cemo uvijek pretpostavljati da je x lijevo dijete od p. Prica je
simetricna ako je x desno dijete.
24
SLUČAJ 1 Pojavljuje se samo
jednom. Izvodi samo jednu rotaciju .
SLUČAJ 2 Pojavljuje se najviše jednom. Ne izvodi
rotacije. Ovo je konačan slučaj.
SLUČAJ 3 Pojavljuje se najviše
O(log n) puta. Ne izvodi rotacije, ali rekurzira.
SLUČAJ 4 Pojavljuje se jednom. Izvodi jednu rotaciju.
SLUČAJ 5 Pojavljuje se najviše jednom. Izvodi jednu
rotaciju. Ovim slučajem procedura završava.
Rekurzivna
petlja
Slika 15. Graficki prikaz povezanosti slucaja.
25
SLUCAJ 1: x-ov brat y je crven. Rotiramo p ulijevo i mijenjamo boje od y i p, ovisno o
bojama djece x-ovog novog brata, koji je bio y-ovo lijevo dijete, a sada je desno dijete od p. To
nas dovodi do slucaja 2, 4 ili 5.
p
x y
p
x
y
Nakon brisanja
Nakon popravljanja
Slika 16. Slucaj 1.
SLUCAJ 2: x-ov roditelj p je crven, y je crn, te y ima dva crna djeteta ili nema
djece. Zamjenimo boje od y i p. To postavlja novi crni cvor iznad x zadrzavajuci jednak broj
crnih cvorova koji prolaze kroz y. Dakle, popravili smo prekrsaj cetvrtog svojstva, pa se procedura
zavrsava.
p
x y
p
x y
Nakon brisanja
Nakon popravljanja
Slika 17. Slucaj 2.
26
SLUCAJ 3: p je crn, y je crn, y ima dva crna djeteta ili nema djece Obojamo y
u crveno. Tada putevima kroz y nedostaje jedan crni cvor, kao i putevima kroz x. Prema tome
sada imamo dvostruki crni cvor u p. Tu pozivamo rekurziju.
p
x y
p
x y
Nakon brisanja
Nakon popravljanja
Slika 18. Slucaj 3.
SLUCAJ 4: y je crn, njegovo desno dijete je crno, a lijevo crveno. Rotiramo y u
desno te pomijenimo boje za y te novo promovirano lijevo dijete. To nas vraca na slucaj 5.
p
yx
p
x
y
Prije popavljanja
Nakon popravljanja
Slika 19. Slucaj 4.
27
SLUCAJ 5: y je crn, a njegovo desno dijete crveno. Rotiramo p lijevo, zamijenimo
boje za y i p i promijenimo y-ovo desno dijete u crno. To postavlja novi crni cvor iznad x
odrzavajuci pri tome jednak broj crnih cvorova koji prolaze kroz yi njegovu djecu.
p
x y
p
x
y
Prije popravljanja
Poslije popravljanja
Slika 20. Slucaj 5.
Da je x originalno bio NIL list, takav bi i ostao nakon bilo kojeg od ovih pet slucaja.
28
5 Prosirenje crveno crnih stabala
Ideja prosirenja strukture podataka je vrlo jednostavna. Zelimo dodati podatke elementima nase
strukture koji nam pomazu da brzo dodemo do nekih tipova informacija. Tehnicki, mozemo
prosiriti strukturu podataka bilo kakvim informacijama, ali ne dozvoljavaju sve informacije efikasno
odrzavanje.
U vecini slucajeva su nam sasvim dovoljne standardne strukture podataka koje su ugradene
u programske pakete, ali ponekad su nam potrebne dodatne operacije. Kako ne bi, svaki puta
kada se nademo u takvoj situaciji, pravili nove strukture od samoga pocetka, nadogradit cemo
postojece strukture. Kako bi se to odradilo sto efikasnije, proces prosirenja cemo podijeliti na
cetiri koraka.
1. Prvo odaberemo standardnu strukturu podataka koju zelimo prosiriti. U nasem slucaju
crveno-crno stablo.
2. Odredimo dodatne informacije koje zelimo ubaciti u odabranu strukturu.
3. Provjerimo da se uneseni podaci mogu odrzavati kod poziva osnovnih operacija.
4. Razvijemo novu operaciju.
U slucaju binarnih struktura podataka, postoji jednostavno pravilo pomocu kojeg mozemo
odrediti koji tip podataka je dobar za prosirenje.
Teorem 5.1 Prosirujemo crveno-crno stablo poljem f, gdje f[x] ovisi iskljucivo o informacijama
u x, lijevi[x] i desni[x] (ukljucujuci i njih same). Tada mozemo odrzati vrijednost od f u svim
cvorovima za vrijeme umetanja i brisanja bez utecaja na O(lgn) izvrsenja.
Dokaz 5.1 Zelimo dokazati da se promjene prilikom umetanja i brisanja pomicu uz stablo te da
se pri tome operacije izvrsavaju u O(lgn) vremenu.
Umetanje: cvor umecemo kao dijete postojeceg roditelja p[x]. Buduci da x nema djece, on utjece
samo na informacije cvora f[p[x]]. Nadalje, promjena u cvoru f[p[x]] utjece na cvor f[p[p[x]]]. Tako
se pomicemo uz stablo, sve do korijena. Svaka ta promjena zahtjeva O(1) vremena. Buduci da
je visina stabla O(lg n), toliko nam je vremena potrebno da izvrsimo promjenu u stablu.
Brisanje: Brisanje funkcionira slicno kao i umetanje. Do promjena dolazi nakon sto je trazeni
cvor izrezan iz stabla te se azurira polje f. Popravak stabla zahtjeva najvise tri rotacije, koje
zahtjevaju O(lg n) vremena. Nadalje, kao i kod umetanja, azuriramo informacije pomicuci se uz
stablo, sto nas kosta O(lg n). To je ukupno O(lg n) vremena.
�
Pogledajmo dva primjera prosirenja crveno-crnog stabla, stablo statistike reda i intervalno
stablo.
29
5.1 Stablo statistike reda
Cilj nam je dizajnirati strukturu podataka koja podrzava umetanje, brisanje i pretrazivanje po
rangu u O(lgn) vremenu.
Kao temeljnu strukturu koju cemo prosirivati biramo crveno-crno stablo T . Svaki cvor x u
tom stablu cemo prosiriti dodatnim poljem, njegovom velicinom, size(x). Velicina cvora x je
broj svih cvorova u podstablu kojemu je x korijen.
size(x) = size(left(x)) + size(right(x)) + 1
13
25
6
3
0 5
9
7 11
12
21
16 23
14 19
17 20
22 24
30
27 48
26 29 43 50
1 1 1
1 1 1
2 1 1 13
3543
8 9
1 1
3
18
1 1
3
7
26
Slika 21. Binarno stablo sa pridruzenim velicinama. Velicina svakog cvora oznacena je crvenim
brojem ispod svakog cvora.
Stablo statistike reda T je struktura koja podrzava pronalazenje i−tog elementa u dinamickom
skupu u O(lgn) vremenu.
Kako bi pronasli i− tu statistiku reda, provodimo binarno pretrazivanje. Neka su a i b velicine
lijevog odnostno desnog djeteta. Tada radimo sljedece:
• Ako je i = a + 1, trenutni cvor sadrzi i− tu statistiku reda.
• Ako je i < a + 1, i− tu statistiku reda trazimo u lijevom podstablu.
• Ako je i > a + 1, trazimo (i− a− 1)− vu statistiku reda u desnom podstablu.
a+b+1
ba
Trazimo i− tu statistiku Trazimo (i− a− 1)-u statistiku
Slika 22.Pretrazivanje statistike reda.
30
Pridrzavajuci se pravila za prosirenje strukture podataka, moramo provjeriti moze li se nova
struktura efikasno azurirati za vrijeme izvodenja operacija.
U slucaju rotacije, polje velicine mijenjamo samo za jedan cvor, i to lijevo dijete ako imamo desnu
rotaciju, te desno dijete ako imamo lijevu rotaciju.
a+b+c+2 a+b+c+2
a+b+1 c
a b
a
b+c+1
b c
Slika 23.Promjena velicine kod rotacija..
Promjena velicine se odvija u konstantnom vremenu. Ukoliko prilikom rotacije dode do
prekrsaja jednog od svojstava crveno-crnog stabla, stablo se popravlja kako smo naveli ranije.
Sveukupno nas ovo azuriranje kosta O(lgn) vremena.
Kako smo do sada vidjeli, proces umetanja se odvija u dvije faze, spustanje niz stablo kako
bi umetnuli cvor, te popravak eventualnih prekrsaja pomicuci ih uz stablo. Nakon sto umetnemo
cvor, penjemo se uz stablo i svakom cvoru na koji naidemo povecavamo velicinu za 1. Svaka ta
promjena nas kosta O(1), a prema tome cijelo azuriranje stabla izvodimo u O(lgn) vremenu.
Gotovo jednaka procedura je i za brisanje.
Dvije su operacije s kojima cemo prosiriti crveno-crno stablo za koje nam je potrebno polje
size[] - pretrazivanje po rangu i racunanje ranga danog elementa.
Za pretrazivanje po rangu cemo koristiti operaciju OS-SELECT(x,i) koja daje pokazivac na i-ti
najmanji element u podstablu s korijenom u x.
Algorithm OS-SELECT(x,i)
1. r ← size[left[x]] + 1
2. if i = r
3. then return x
4. else if i < r
5. then return OS-SELECT(left[x], i)
6. else return OS-SELECT(right[x], i - r)
Ova procedura prije svega racuna rang danog cvora x, u smislu inorder obilaska stabla. Dakle,
rang cvora x jednak je velicini lijevog podstabla kojemu je x korijen, ukljucujuci sam x. Trazeni i
usporedujemo sa dobivenim rangom te se pomicemo kako je to prikazano na slici 24 i rekurziramo
na novom cvoru. Svaki rekurzivni poziv se odvija u konstantnom vremenu, a svakim pozivom se
31
spustamo jednu razinu nize u stablu. To znaci da cijela procedura moze biti najvise proporcionalna
visini stabla, pa nas kosta najvise O(lgn).
13
25
6
3
0 5
9
7 11
12
21
16 23
14 19
17 20
22 24
30
27 48
26 29 43 50
OS-SELECT(25,14)
OS-SELECT(13,14)
OS-SELECT(21,5)
OS-SELECT(16,5)
OS-SELECT(19,3)
OS-SELECT(20,1)
Slika 24.Primjer izvrsenja operacije OS-SELECT(x,i).
Druga procedura nam je potrebna kako bi izracunali rang danog elementa.
Algorithm OS-RANK(T,x)
1. r ← size[left[x]] + 1
2. y ← x
3. while y 6= root[T ]
4. do if y = right[p[y]]
5. then r ← r + size[left[p[y]]] + 1
6. y ← p[y]
7. return r
Procedura OS-RANK racuna rang danog elementa prebrajajuci elemente stabla koji dolaze
prije njega u inorder obilasku stabla. Glavni dio operacije je while petlja koja racuna r. U svakoj
se iteraciji pomicemo za jedan nivo uz stablo, sve do korijena. Ukoliko je promatrani cvor y desno
dijete svog roditelja, prethodno izracunatom rangu dodajemo rang njegovog roditelja, jer se on
nalazi ispred njega. Ukoliko je y lijevo dijete, ne mijenjamo r, jer mu je roditelj u inorder obilasku
stabla s desne strane i ne utjece na njegov rang. Pogledajmo primjer
Iteracija key(x) r1. 19 22. 16 43. 21 44. 13 135. 25 13
32
13
25
6
3
0 5
9
7 11
12
21
16 23
14 19
17 20
22 24
30
27 48
26 29 43 50
penjemo se u lijevo:r = r + size[left[p[y]]] + 1
penjemo se u desno:r se ne mijenja
r=2
r=4
r=4
r=13
Slika 25.Primjer izvrsenja operacije OS-RANK(x,i).
Buduci da svaka iteracija while petlje zauzima O(1) vremena, te da y ide jednu razinu gore
uz stablo svakom iteracijom, vrijeme izvrsenja cjelokupne petlje je najvise proporcionalna visini
stabla, tj. O(lgn).
5.2 Intervalna stabla
Struktura podataka u obliku intervalnog stabla se moze koristiti u slucajevima kada trebamo
pronaci intervale koji se preklapaju u danom skupu intervala. Ova se struktura cesto upotrebljava
u 3D i drugim grafickim sustavima za izracun vidljivih zona.
Interval I = [t1, t2] mozemo prikazati kao objekt sa elementima t1 = low[I] i t2 = high[I].
Za bilo koja dva intervala I1 i I2 vrijedi INTERVALNA TRIHOTOMIJA, tj. uvijek vrijedi jedno
od sljedecih tvrdnji:
• I1 i I2 se preklapaju.
• high[I1] > low[I2]
• high[I2] < low[I1]
Intervalno stablo je crveno crno stablo kojemu svaki cvor sadrzi interval int[x]. Kljuc svakog
elementa je njegova donja granica, low[int[x]], po kojemu sortiramo elemente. Svaki interval
ujedno sadrzi i max[x] vrijednost koja predstavlja maksimalnu vrijednost svih krajnjih tocaka
intervala pohranjenih u podstablu korijena x.
33
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
[13,17]
25
[6,8]
12
[21,23]
25
[3,6] [9,11]
6 12
[7,12]
12
[16,19]
24
[23,25]
25
[19,24]
24
[24,25]
25
Slika 26. Prikaz intervalnog stabla.
Nakon sto smo prosirili stablo, potrebno je pokazati da se operacije mogu i dalje izvoditi u
O(lgn) vremenu.
Operacije umetanja i brisanja izvodimo kao i do sada.
Buduci da vrijednost max[x] svakog cvora mozemo izracunati iz vrijednosti njegove djece, na
sljedeci nacin
max[x] = max(high[int[x]],max[left[x]],max[right[x]])
Tada se po teoremu 4.1. operacije umetanja i brisanja izvode u O(lgn) vremenu.
Nakon sto smo pokazali da osnovne funkcije crveno crnog stabla i dalje vrijede, zelimo dodati novu
operaciju. U slucaju intervala, zelimo pronaci intervale koji se preklapaju. U tu svrhu definiramo
novu funkciju za pretrazivanje.
Algorithm INTERVAL-SEARCH(T, i)
1. x← root[T ]
2. while x 6= nil[T ] & i ne preklapa int[x]
3. do if left[x] 6= nil[T ] & max[left[x]] ≥ low[i]
4. then x← left[x]
5. else x← right[x]
6. return x
34
Ova funkcija je vrlo jednostavna i radi na principu klasicnog pretrazivanja. Odmah na pocetku
postavljamo za x da je korijen stabla. Ukoliko je left[x] = nil[T ] lijevo podstablo ne sadrzi
interval koji preklapa i pa prelazimo na desno podstablo. Pretpostavimo li da je left[x] 6= nil[T ]
i max[left[x]] < low[i], tada za svaki interval i′ iz x-ovog lijevog podstabla imamo
high[i′] ≤ max[left[x]] < low[i]
i i i′ se ne preklapaju pa prelazimo na desno podstablo. Opcenito vrijedi da ukoliko nema
intervala koji preklapa i u podstablu s korijenom u left[x], tada ni jedan interval iz cijelog stabla
ne preklapa i. Buduci da se izvodi 4. linija navedenog algoritma, tada zbog uvjeta iz linije 3
imamo max[left[x]] ≥ low[i]. To znaci da mora postojati interval i′ u x-ovom lijevom podstablu
takav da je
high[i′] = max[left[x]] ≥ low[i]
Kako se i i i′ ne preklapaju i da nije high[i′] < low[i], vrijedi high[i] < low[i′]. Prema tome
slijedi za bilo koji interval i′′ iz x-ovog desnog podstabla
high[i] < low[i′] ≤ low[i′′]
i i i′ se ne preklapaju. To znaci da je postavka x = left[x] bez obzira na to ima li intervala
koji preklapa i u lijevom podstablu ili ne. Ukoliko dodemo do x = nil[T ], nema preklapajuceg
intervala u podstablu s korijenom u x. Prema tome, nema preklapajuceg intervala u cijelom
stablu pa algortam vrav ca x = nil[T ].
Ova funkcija vraca prvi interval na koji naide da preklapa i. No, sto ukoliko imamo vise
preklapajucih intervala. Imamo dvije mogucnosti. Prva mogucnost je da mijenjamo stablo.
To radimo tako da uklonimo svaki preklapajuci interval na koji naidemo te ih na kraju ponovo
umecemo. To traje O((k + 1)lgn) vremena. Zaustavljamo se kad je k = nlogn
buduci da je
problem trivijalno rjesiv u O(n) vremenu ispitivanjem svih intervala. Ako ne zelimo mijenjati
stablo, tada modificiramo funkciju pretrazivanja kako bi pronasli preklapajuci interval koji ima
minimalnu krajnju tocku.
Algorithm MIN-INTERVAL-OVERLAP(T,i)
1. x ←root[T ]
2. while x 6= NIL
3. do if left[x] 6= NIL i max[left[x]] ≥ low[i]
4. then c← left[x]
5. else if i overlap int[x]
6. then return x
7. x ←right[x]
8. return NIL
35
Ovaj algoritam ponavljamo nekoliko puta uzastopce, ali ne brisemo preklapajuce intervale,
nego koristimo dva skupa intervala A i B. Prilikom prolaska kroz stablo od korijena prema listo-
vima, guramo cvorove koje smo obisli u A. Kada pronademo preklapajuci interval sa minimalnom
krajnjom tockom, vracamo se istim putem gore. Tada uzimamo cvorove iz A i stavljamo ih u B
te mijenjamo max vrijednost preklapajuceg intervala kako ga ne bi ponovo ocitavali. Kada se
ponovo pokrene funkcija pretrazivanja, pretrazujemo intervale iz skupa B, pri cemu vec poznati
preklapajuci interval nevidimo. Taj proces nastavljamo sve dok ne izlistamo sve preklapajuce
intervale.
[13,17]
25
[6,8]
12
[21,23]
25
[3,6] [9,11]
6 12
[7,12]
12
[16,19]
24
[23,25]
25
[19,24]
24
[24,25]
25
i=[20,23]x = [13, 17]max[left[x]] = 12low[i] = 20 > 12idemo u desno
max = 24low = 20 < 24idemo u lijevo
ovaj interval preklapa iispisujemo ga i nastavljamo dalje
Ne preklapa iNema lijevo dijeteIdemo u desno
Preklapa iIspisujemo ga i zaustavljamo se
Slika 27. Primjer pretrage na intervalnom stablu.
36
Literatura
[1] Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein, Introduction to
Algorithms,Second edition, MIT Press, London, England, 2003.
[2] A. Anderson, Balanced search trees made simple, In proceedings of the 3rd workshop on
algorithms and data structures, pp 290-306, 1993.
[3] R. Sedgewick Algorithms in C++, Third edition, Part 1-4, Addison Weasly Publishing
Company, Inc., 1998.
[4] Robert E. Tarjan, Data structures and network algorithms, Bell Laboratories, Murray Hill,
New Jersey, 2008.
[5] Donald E. Knuth, The art of computer programming, Vol 1, Third edition, Addison-Wesley
[6] Donald E. Knuth, The art of computer programming, Vol 3, Addison Wesley Publiching
Company
[7] Video predavanje prof. E. Demaine, snimljen 2005. na Massachusetts Institute of Technology,
MIT
Sazetak. U radu je obradena struktura podataka pogodna za rad sa velikim bazama po-
dataka. Crveno crna stabla su specificna stablasta struktura podataka kojoj je glavno svojstvo
da svaki cvor mora imati boju, bilo crnu ili crvenu. Pokazano je da je moguce odrzati sve os-
novne operacije, pretrazivanje, umetanje i brisanje. Prilikom izvodenja operacija moze doci do
prekrsaja nekog od svojstava, pa se pozivaju funkcije za popravak. Zato kazemo da su crveno
crna stabla samobalansirajuce strukture podataka. Popravci se sastoje od rotacija te promjena
boja cvorovima koji su u direktnom prekrsaju. Svaka pojedina funkcija popravka se odvija u
konstantnom vremenu. Danu strukturu podataka je takoder moguce prosiriti novim vrijednos-
tima i operacijama, a da pri tome zadrzimo optimalno vrijeme izvrsenja svih osnovnih operacija.
Primjeri takvih prosirenja su stabla statistike reda i intervalna stabla. Sve operacije na crveno
crnom stablu su u najgorem slucaju proporcionalne visini stabla, O(logn).
Kljucne rijeci. Binarna stabla pretrazivanja, crveno crna stabla, inorder obilazak stabla,
vrijeme izvrsenja algoritma, stablo statistike reda, intervalno stablo.
Abstract. In this paper we talk about data structure that is sutable for dealing with large
data bases. Red black trees are specific tree data structure in which every node has color, red
or black. It is shown that red black trees support all basic operations, like searching, insertion
and deletion. During insertion or deletion some rules may be broken, so we call for the fixup
procedures. Thus we say that red black trees are selfbalancing data structures. Fixup procedure
contains rotations and color flips on nodes that are in direct violation. Each of fixup procedures
take constant time. This data structure can be augmented with new values and operations, and
still have optimal running time. Examples of augmentation are order statistic tree and interval
tree. All operations on red black tree are in worst case proportional to the hight of the tree,
O(logn).
Key words. Binary search tree, red black tree, inorder tree traversal, running time, order
statistic tree, interval tree.
ZIVOTOPIS
Sanela Bulic Jojkic je rodena 24. svibnja 1985. godine u Osijeku. 1992. godine je upisala
Osnovnu skolu u Osijeku. Tijekom osnovne skole je sudjelovala na gradskim i zupanijskim natje-
canjima iz fizike. 2000. godine upisuje Prirodoslovno matematicku Gimnaziju u Osijeku. 2004.
godine upisuje Odjel za fiziku Sveucilista J. J. Strossmayera u Osijeku ali se nakon prvog semestra
prebacuje na Odjel za matematiku, na Sveucilisni nastavnicki smjer matematike i informatike.