811312A Tietorakenteet ja algoritmit 2016-2017 IV Perustietorakenteet
Sisältö 1. Johdanto 2. Pinot, jonot ja listat 3. Hash-taulukot 4. Binääriset etsintäpuut 5. Puna-mustat puut 6. Tietorakenteiden täydentäminen 811312A TRA, Perustietorakenteet 2
IV.1. Johdanto Määritelmä: Tietorakenne on äärellinen dynaaminen joukko, joka toteuttaa rajapintanaan sarjan operaatioita joiden kautta algoritmi voi muokata joukkoa. Tietorakenteen sisäinen rakenne: Joukko alkioita Alkioilla sisäinen rakenne Alkioihin voidaan yksikäsitteisesti osoittaa osoittimella Alkio sisältää joukon kenttiä, yleensä ainakin Avain, käytetään alkioiden vertailuun Satelliittidata, talletettuna alkioon mutta merkityksetön tietorakenteen sisäisen toiminnan kannalta 811312A TRA, Perustietorekenteet 3
IV.1.1 Dynaamiset joukot Kutsutaan myös sanakirjoiksi (dictionary) Operaatiot: ETSI(S, k) Etsii joukosta S alkion, jonka avain on k. LISÄÄ(S, x) Lisää alkion x joukkoon S POISTA(S, x) Poistaa alkion x joukosta S MINIMI(S) Etsii pienimmän alkion täydellisesti järjestetystä joukosta S 811312A TRA, Perustietorakenteet 4
IV.1.1 Dynaamiset joukot (2) Operaatiot jatkuu MAKSIMI(S) Etsii suurimman täydellisesti järjestetystä joukosta S SEURAAJA(S, x) Etsii täydellisesti järjestetystä joukosta S alkiosta x seuraavaksi suuremman EDELTÄJÄ(S, x) Etsii täydellisesti järjestetystä joukosta S alkiosta x seuraavaksi pienemmän HUOM! Tietorakenteessa käytettävän dynaamisen joukon ei tarvitse välttämättä tukea kaikkia operaatioita! 811312A TRA, Perustietorakenteet 5
IV.2. Pinot, jonot ja listat IV.2.1. Pino (stack) Yksinkertainen tietorakenne, joka toimii LIFOperiaatteella (Last In First Out) Viimeksi lisätty alkio otetaan ensimmäisenä pois Viimeksi lisätty alkio pinon pää tai huippu (top) Voidaan käyttää esimerkiksi järjestyksen kääntämiseen, rekursiivisten kutsujen toteuttamiseen jne. 811312A TRA, Perustietorakenteet 6
IV.2.1.1 Pinon operaatiot Taulukolla toteutettu pino: a) Pinossa 2,4,5 b) Lisätty 7 ja 2: pino täysi c) Poistettu 2, huipulla 7 811312A TRA, Perustietorakenteet 7
IV.2.1.1 Pinon operaatiot (2) PINO_TYHJÄ(S) 1. if S.head == 0 2. return TRUE 3. else 4. return FALSE PINO_LISÄÄ(S,x) # PUSH 1. S.head = S.head + 1 2. S[S.head] = x 811312A TRA, Perustietorakenteet 8
IV.2.1.1 Pinon operaatiot (3) PINO_POISTA(S) # POP 1. if PINO_TYHJÄ(S) 2. error Alivuoto 3. else 4. S.head = S.head 1 5. return S[S.head + 1] HUOM! Toteutettu taulukolla, jonka ensimmäinen indeksi on 1 Kaikki operaatiot vakioaikaisia, jos toteutetaan taulukolla -> Pino erittäin tehokas tietorakenne 811312A TRA, Perustietorakenteet 9
IV.2.2 Jono (queue) Yksinkertainen tietorakenne, joka toimii FIFOperiaatteella (First In First Out) Ensiksi lisätty alkio otetaan ensimmäisenä pois Jonon ensimmäinen alkio on pää tai keula (head). Häntä (tail) osoittaa paikkaan viimeisen alkion jälkeen Voidaan käyttää järjestyksen ylläpitoon Toteuttaa ainakin seuraavat operaatiot: jonoon lisääminen (enqueue) ja jonosta poisto (dequeue) 811312A TRA, Perustietorakenteet 10
IV.2.2.1 Jonon operaatiot Taulukolla toteutettu jono: 811312A TRA, Perustietorakenteet 11
IV.2.2.1 Jonon operaatiot (2) JONO_LISÄÄ(Q,x) 1. Q[Q.tail] = x 2. if Q.tail == Q.pituus 3. Q.tail = 1 4. else 5. Q.tail = Q.tail + 1 JONO_POISTA(Q) 1. x = Q[Q.head] 2. if Q.head == Q.pituus 3. Q.head = 1 4. else 5. Q.head = Q.head + 1 HUOM! Toteutettu taulukolla -> operaatiot vakioaikaisia HUOM2! Ei varauduttu ali- ja ylivuotoon 6. return x 811312A TRA, Perustietorakenteet 12
IV.2.3 Linkitetty lista Linkitetyissä listoissa alkiot (solmut) ovat järjestyneet peräkkäisesti (lineaarisesti) Peräkkäisyys määräytyy osoittimilla solmusta seuraavaan solmuun Jokainen alkio siis sisältää osoittimen Lista voi olla myös kahteen suuntaan linkitetty, ts. solmussa osoitin sekä seuraajaan että edeltäjään 811312A TRA, Perustietorakenteet 13
IV.2.3.1 Linkitetyn listan toteutusvaihtoehdot a) Tavallinen yhteen suuntaan linkitetty lista b) Kahteen suuntaan linkitetty lista c) Renkaaksi linkitetty lista 811312A TRA, Perustietorakenteet 14
IV.2.3.1 Kahteen suuntaan linkitetyn listan operaatiot LISTA_ETSI(L,k) 1. x = L.head 2. while x NIL and x.key k 3. x = x.next 4. return x LISTA_LISÄÄ(L,x) 1. x.next = L.head 2. if L.head NIL 3. (L.head).previous = x 4. L.head = x 5. x.previous = NIL 811312A TRA, Perustietorakenteet 15
IV.2.3.1 Kahteen suuntaan linkitetyn listan operaatiot (2) LISTA_POISTA(L,x) 1. if x.previous NIL 2. (x.prevous).next = x.next 3. else 4. L.head = x.next 5. if x.next NIL 6. (x.next).previous = x.previous 811312A TRA, Perustietorakenteet 16
IV.2.3.2 Linkitetyn listan operaatioiden aikakompleksisuus Lisääminen ja poistaminen vakioaikainen Ellei poistettavaa tarvitse ensin etsiä Etsiminen lineaariaikainen 811312A TRA, Perustietorakenteet 17
IV.3 Hash-taulukot Käytetään toteutettaessa tietoalkiojoukko, johon voidaan kohdistaa lisäys- poisto- ja hakuoperaatioita Apuna tiiviste- eli hashfunktiot Oletus: Tietoalkioissa yksilöllinen avainkenttä Suora osoittaminen: Varataan taulukko, jossa paikka jokaiselle avainkentän arvolle Operaatiot nopeita Ongelma: Yleensä arvoja liikaa 811312A TRA, Perustietorakenteet 18
IV.3 Hash-taulukot (2) Pienennetään tallennustaulukon kokoa T[1..m] m (paljon) pienempi kuin avainten lukumäärä Tarvitaan funktio h avaimilta joukolle {1,,m} Ns. tiivistefunktio (hash function) Tietoalkion avain k: tallennetaan paikkaan T[h(k)] Operaatiot tehokkaita (vakioaika) Törmäysongelma: Jotkin avaimet kuvautuvat samalle arvolle Väistämätöntä, koska arvoja vähemmän kuin avaimia 811312A TRA, Perustietorakenteet 19
IV.3.1 Törmäysongelma Ratkaisu: ketjutetaan samalle arvolle kuvautuvat avaimet Taulukkoon osoitin linkitettyyn listaan Tietoalkio löytyy listaa seuraamalla Seuraus: Operaatiot eivät enää vakioaikaisia 811312A TRA, Perustietorakenteet 20
T Kaikki avaimet / k 4 k 8 / Käytetyt avaimet k 8 / k 1 k 2 k 7 / k 2 k 1 k 4 k 3 k 7 k 5 k 6 h(k 1 ) = h(k 2 ) = h(k 7 ) / / / / k 3 k 5 / k 6 / h(k 4 ) = h(k 8 ) h(k 3 ) = h(k 5 ) Törmäysongelman ratkaiseminen ketjuttamalla
IV.3.1 Törmäysongelma (2) Oletetaan, että tallennettuja avaimia n kappaletta -> keskimäärin yhteen taulukon paikkaan n/m avainta, jos tiivistefunktio jakaa avaimet tasaisesti Suhde n/m on taulukon täyttöaste Listan pään hakeminen on vakioaikainen operaatio Listaoperaatioiden lukumäärä suoraan verrannollinen listan pituuteen Keskimäärin n/m Siis operaatioiden keskimääräinen kompleksisuus luokkaa O(1+n/m) 811312A TRA, Perustietorakenteet 22
IV.3.2. Millainen on hyvä tiivistefunktio? Riippuu käyttötarkoituksesta Tietoalkioiden tallennuksen ja haun tehokkuus: Kuvaa arvot mahdollisimman tasaisesti Tietoturvasovellukset: Minimoi törmäykset, estää avaimen arvaamisen kun tiiviste tunnetaan 811312A TRA, Perustietorakenteet 23
IV.3.3. Erilaisia tiivistefunktioita Oletus: Avaimet lukuja 0,1,2,3, Jakomenetelmä: h( k) k(mod m) m valittava sopivasti: yleensä alkuluku Esimerkki: avaimia 10000 ja voidaan tallentaa keskimäärin 10 avainta samaan listaan. Valitaan m alkuluvuksi läheltä lukua 1000, esim. m = 1009 811312A TRA, Perustietorakenteet 24
IV.3.3. Erilaisia tiivistefunktioita (2) Tulomenetelmä: h( k) m ( ka(mod1)) A jokin reaalilukuvakio 0 < A < 1 Etu: Ei riipu kriittisesti luvusta m 811312A TRA, Perustietorakenteet 25
Tulomenetelmän implementointi: Sanan pituus w Valitaan m=2 p, s väliltä (0,2 w ) A = s/2 w w bittiä k s=a 2 w k s: r 1 r 0 p bittiä = h(k)
IV.3.4. Avoin osoittaminen Ei ketjuteta avaimia, vaan etsitään taulukosta vapaa paikka niin kauan kuin mahdollista Yksi menetelmä luotaaminen (probing): tiivistefunktio riippuu avaimen lisäksi parametrista, jonka arvot voivat olla 0,...,m-1, kun taulukon koko on m Avain k yritetään tallentaa ensiksi paikkaan h(k,0) ja jos varattu, paikkaan h(k,1), h(k,2) jne. kunnes löytyy vapaa kohta Hyöty verrattuna tavalliseen taulukkoon tallentamiseen: ei aloiteta aina taulukon alusta, vaan avaimesta riippuvasta arvosta; lisäksi luotausjono riippuu myös avaimesta k-> törmäysten mahdollisuus vähenee 811312A TRA, Perustietorakenteet 27
IV.3.4. Avoin osoittaminen: Tallennus Syöte: Taulukko T[1,..,m], m >= 1, lisättävä avain k Tulostus: Taulukon indeksi, johon avain lisätään tai arvo OVERFLOW jos taulukko oli täynnä. HASH_TALLENNA(T,k) 1. i = 0 2. while i<m 3. j = h(k,i) 4. if T[j]==NIL 5. T[j]=k 6. return j 7. i = i+1 8. return OVERFLOW 811312A TRA, Perustietorakenteet 28
IV.3.4. Avoin osoittaminen: Haku (3) Syöte: Taulukko T[1,..,m], m >= 1, etsittävä avain k Tulostus: Taulukon indeksi, josta avain löydetään tai arvo NIL jos avain ei ole taulukossa. HASH_ETSI(T,k) 1. i = 0 2. j = h(k,i) 3. while (i<m && T[j]!=NIL) 4. if T[j]==k 5. return j 6. i = i+1 7. if i<m 8. j = h(k,i) 9. return NIL 811312A TRA, Perustietorakenteet 29
IV.3.4. Avoin osoittaminen: Poistaminen Avaimen poistaminen ei aivan näin suoraviivaista Voidaan joutua poistamaan luotausjonon keskeltä Voitaisiin käyttää erikoisarvoa DEL merkitsemään tuhotut -> etsittäessä ohitetaan nämä arvot Jos poistoja usein kannattaa mieluummin ketjuttaa Luotauksen etuja: Rajoitettu muistin käyttö ja helpompi osoittaminen 811312A TRA, Perustietorakenteet 30
IV.3.4.1 Erilaisia luotausmenetelmiä Lineaarinen luotaus: Tunnetaan jokin tiivistefunktio f (esimerkiksi tulomenetelmällä saatu) Nyt käytetään tiivistefunktiota h( k, i) ( f ( k) i)(mod m) Helppo implementoida Jokaisella avaimelle luotausjono sisältää kaikki arvot 0..m Kasautumisongelma: Avain sattuu todennäköisemmin pitkään varattuun jonoon kuin lyhyeen ja haku hidastuu 811312A TRA, Perustietorakenteet 31
IV.3.4.1 Erilaisia luotausmenetelmiä (2) Neliöllinen luotaus Tunnetaan jokin tiivistefunktio f Nyt käytetään tiivistefunktiota h( k, i) ( f ( k) 2 c1 i c2 i )(mod m) c 1 ja c 2 positiivisia vakioita Kasautumisongelma poistuu Vakiot valittava taulukon kokoon sopivasti 811312A TRA, Perustietorakenteet 32
IV.3.4.1 Erilaisia luotausmenetelmiä (3) Kaksoishashaus Pidetään yhtenä parhaimmista menetelmistä Tunnetaan kaksi tiivistefunktiota f ja g Tällöin tiivistefunktio on h( k, i) ( f ( k) i g( k))(mod m) Erilaisia luotausjonoja noin m 2 kappaletta Funktio on valittava sopivasti, jotta jonot sisältäisivät kaikki arvot Sopivasti toteutettuna lähellä ideaalitapausta 811312A TRA, Perustietorakenteet 33
IV.3.5. Tiivistefunktioiden muita sovelluksia Tarkistussumma: Viesti k ja sen tiiviste h(k) Lähetetään pari (k,h(k)) -> Vastaanottaja voi tarkistaa, onko viesti muuttunut matkalla Huom! Ei yleensä suojaa tarkoitukselliselta muuttamiselta MAC-funktio (Message Authentication Code): Tiiviste riippuu viestistä ja avaimesta, joka ainoastaan lähettäjällä ja vastaanottajalla Funktion oltava vaikea väärentää, ts. kun h(k) tunnetaan, hankala keksiä sellaista viestiä m, että h(m)=h(k) 811312A TRA, Perustietorakenteet 34
IV.4 Binääriset etsintäpuut T binääripuu ja x sen solmu. Merkinnät: T.root osoitin puun juureen x.left osoitin solmun x vasempaan alipuuhun x.right osoitin solmun x oikeaan alipuuhun x.p osoitin solmun x vanhempaan 811312A TRA, Perustietorakenteet 35
IV.4 Binääriset etsintäpuut (2) Binäärinen etsintäpuu (binäärinen hakupuu, binary search tree) on binääripuu, jossa solmun avain on aina suurempi tai yhtä suuri kuin solmujen arvot sen vasemmassa alipuussa ja pienempi tai yhtä suuri kuin solmujen arvot oikeassa alipuussa. Binäärisessä etsintäpuussa pätee siis x.left.key <= x.key <= x.right.key HUOM! Jokainen alipuu on edelleen etsintäpuu Rekursiivisen rakenteen vuoksi helppo käsitellä algoritmisesti 811312A TRA, Perustietorakenteet 36
Esimerkki binäärisestä hakupuusta 20 10 28 8 16 27 14 18 811312A TRA, Perustietorakenteet 37
IV.4.1 Binäärisen etsintäpuun läpikäynti Syöte: Binäärisen etsintäpuun solmu x Tulostus: Tulostaa solmusta x lähtevän alipuun avaimet suuruusjärjestyksessä BST_SISÄJÄRJESTYS(x) 1. if x!= NIL 2. BST_SISÄJÄRJESTYS(x.left) 3. tulosta x.key 4. BST_SISÄJÄRJESTYS(x.right) Siis kutsu BST_SISÄJÄRJESTYS(T.root) tulostaa kaikki puun avaimet suuruusjärjestyksessä 811312A TRA, Perustietorakenteet 38
IV.4.2 Haku binäärisestä etsintäpuusta Syöte: BST:n juuri x, etsittävä avain k Tulostus: Palauttaa osoittimen solmuun joka sisältää avaimen tai arvon NIL jos avain ei ole puussa. BST_ETSI(x,k) 1. y = x 2. while y!=nil && y.key!=k 3. if y.key < k // k oikealla 4. y = y.right 5. else // k vasemmalla 6. y = y.left 7. return y Kompleksisuus luokkaa Ɵ(h) missä h on puun korkeus 811312A TRA, Perustietorakenteet 39
IV.4.3 Binäärisen etsintäpuun minimi ja maksimi Syöte: Binäärisen etsintäpuun juuri x Tulostus: Palauttaa osoittimen solmuun joka sisältää puun pienimmän /suurimman avaimen tai arvon NIL, jos puu on tyhjä. BST_MINIMI(x) 1. if x==nil 2. return NIL 3. y = x 4. while y.left!=nil 5. y = y.left 6. return y BST_MAKSIMI(x) 1. if x==nil 2. return NIL 3. y = x 4. while y.right!=nil 5. y = y.right 6. return y Kompleksisuudet luokkaa Ɵ(h) missä h on puun korkeus 811312A TRA, Perustietorakenteet 40
IV.4.4 Avaimen lisääminen Syöte: Binäärinen etsintäpuu T ja lisättävä avain k Tulostus: Lisää avaimen sisältävän solmun puun lehtisolmuksi. 10. else if k > x.key BST_LISÄÄ(T,k) 11. x=x.right 1. Uusi solmu t 12. else 2. t.key = k 13. return 3. t.left = NIL 14. t.p = y 4. t.right = NIL 15. if y==nil 5. x = T.root 16. T.root = t 6. while x!= NIL 17. else if k < y.key 7. y=x 18. y.left = t 8. if k < x.key 19. else 9. x=x.left 20. y.right = t 21. return 41
IV.4.4 Avaimen poistaminen Avain lehtisolmussa: 20 20 10 25 10 25 8 16 28 8 16 28 14 18 27 30 14 27 30 12 12 13 13 811312A TRA, Perustietorakenteet 42
IV.4.4 Avaimen poistaminen (2) Avain solmussa, jolla yksi alipuu 20 20 10 25 10 28 8 16 28 8 16 27 30 14 18 27 30 14 18 12 12 13 13 811312A TRA, Perustietorakenteet 43
IV.4.4 Avaimen poistaminen (3) Avain solmussa jolla kaksi alipuuta 20 10 25 12 20 10 25 8 16 28 8 16 28 14 18 27 30 14 18 27 30 12 13 13 20 12 25 8 16 28 14 18 27 30 13 811312A TRA, Perustietorakenteet 44
IV.4.4 Avaimen poistaminen: apualgoritmi Syöte: Binäärinen etsintäpuu T ja sen solmut u ja v (v voi olla NIL) Tulostus: Binäärinen etsintäpuu, jossa solmusta u lähtevän alipuun tilalle on siirretty solmusta v lähtevä alipuu BST_TRANSPLANT(T,u,v) 1. if u.p == NIL // u oli juuri 2. T.root = v 3. else if u == u.p.left // u vas. alipuussa 4. u.p.left = v 5. else 6. u.p.right = v // u oik. alipuussa 7. if v!= NIL 8. v.p = u.p 811312A TRA, Perustietorakenteet 45
IV.4.4 Avaimen poistaminen: algoritmi Syöte: BST T ja poistettava avain k Tulostus: Poistaa avaimen puusta, jos se esiintyy. Paluu: TRUE,jos avain puussa, FALSE muuten. HUOM: BST_TR = BST_TRANSPLANT ja BST_MIN = BST_MINIMI 10. if y.p!= x BST_POISTA(T,k) 11. BST_TR(T,y,y.right) 1. x = BST_ETSI(T,k) 12. y.right = x.right 2. if x == NIL 13. y.right.p = y 3. return FALSE 14. BST_TRANSPLANT(T,x,y) 4. if x.left == NIL 15. y.left = x.left 5. BST_TR(T,x,x.right) 16. y.left.p = y 6. else if x.right == NIL 17. return TRUE 7. BST_TR(T,x,x.left) 8. else 9. y = BST_MIN(x.right) 46
IV.4.5 Avaimen lisääminen ja poistaminen: kompleksisuus Lisääminen: Jokaisella silmukan kierroksella syvemmälle puussa, silmukassa vakioaikaisia operaatioita -> kompleksisuus luokkaa Ɵ(h) missä h on puun korkeus Poistaminen: BST_TRANSPLANT vakioaikainen, muuten vakioaikaisia operaatioita paitsi yksi BST_ETSI ja korkeintaan yksi BST_MINIMI -> kompleksisuus luokkaa Ɵ(h) missä h on puun korkeus HUOM! Puun rakenteesta riippuu miten solmujen lukumäärä suhtautuu puun korkeuteen Yleisesti tiedetään vain että h <= n Jos puu tasapainossa niin n luokkaa 2 h 811312A TRA, Perustietorakenteet 47
IV.5 Puna-mustat puut Yksi tapa pitää puu tasapainossa myös solmuja lisättäessä ja poistettaessa Binäärinen hakupuu on puna-musta puu, jos 1-5 voimassa: 1. Jokainen solmu on joko punainen tai musta. 2. Juuri on musta. 3. Jokainen lehti (NIL) on musta. 4. Jos solmu on punainen, sen molemmat lapset ovat mustia. 5. Kaikille solmuille on voimassa: Jokainen polku solmusta sen jälkeläislehtiin sisältää saman lukumäärän mustia solmuja. 811312A TRA, Perustietorakenteet 48
Esimerkki: ehdot eivät voimassa 20 20 10 25 10 25 8 16 28 8 16 28 14 18 27 30 14 27 30 Yo. puut eivät puna-mustia. Miksi? 811312A TRA, Perustietorakenteet 49
Esimerkki: Ehdot voimassa 20 10 25 8 16 24 28 14 18 27 30 Puna-musta puu. Tarkista ehdot 1-5! 811312A TRA, Perustietorakenteet 50
IV.5.1 Puna-mustan puun korkeus Solmun x mustakorkeus bh(x) on sen mustien jälkeläisten lukumäärä polussa solmusta x puun lehteen saakka Puna-mustalle puulle voimassa: Alipuu, jonka juuri x on, sisältää vähintään 2 bh(x) -1 solmua Ylläolevasta seuraa: Jos puna-mustassa puussa n solmua ja sen korkeus on h, niin h 2lg(n+1) Puu on siis riittävän tasapainossa, jotta operaatiot voisivat olla logaritmisia 811312A TRA, Perustietorakenteet 51
IV.5.2 Puna-mustien puiden operaatiot Binääristen hakupuiden BST_ETSI, BST_MINIMI, BST_MAKSIMI soveltuvat sellaisinaan Näiden kompleksisuus Ɵ(h), missä h puun korkeus Jos solmuja n, niin ehdon h 2lg(n+1) ja edellisen nojalla kompleksisuus Ɵ(lg(n)) Lisäämiselle ja poistamiselle uudet operaatiot, jotta puna-musta-ominaisuus pysyy voimassa 811312A TRA, Perustietorakenteet 52
IV.5.2 Puna-mustien puiden operaatiot: rotaatio x RBT_VASEN_ROTAATIO(T,x) y a y RBT_OIKEA_ROTAATIO(T,y) x c b c a b Vasen ja oikea rotaatio graafisesti Rotaatioita tarvitaan rakenteen ylläpitoon 811312A TRA, Perustietorakenteet 53
IV.5.2.1 Vasen rotaatio Syöte: Binäärinen etsintäpuu T ja solmu x, jonka suhteen kierretään. Oletus: x.right!= NIL Tulostus: Suorittaa puussa vasemman rotaation solmun x suhteen RBT_VASEN_ROTAATIO(T,x) 1. y = x.right 2. x.right = y.left 3. if y.left!= NIL 4. y.left.p = x 5. y.p = x.p 6. if x.p == NIL 7. T.root = y 8. else if x == x.p.left 9. x.p.left = y 10. else 11. x.p.right = y 12. y.left = x 13. x.p = y 14. return Operaatio vakioaikainen Oikea rotaatio tehdään symmetrisesti 54
IV.5.2.2 Puna-mustaan puuhun lisääminen Syöte: Puna-musta puu T ja solmu z, jonka avain on lisättävä avain. Tulostus: Lisää avaimen z.key puuhun niin, että T säilyy puna-mustana. RBT_LISÄÄ(T,z) 1. y = NIL 2. x = T.root 3. while x!= NIL 4. y = x 5. if z.key < x.key 6. x = x.left 7. else 8. x = x.right 9. z.p = y 10. if y == NIL 11. T.root = z 12. else if z.key < y.key 13. y.left = z 14. else 15. y.right = z 16. z.left = NIL 17. z.right = NIL 18. z.color = RED 19. RBT_LISÄYS_KORJAUS(T,z) 55
IV.5.2.2 Puna-mustaan puuhun lisääminen (2) Syöte: Puu T ja solmu z, joka on lisätty T:hen. T on ollut puna-musta puu ennen z:n lisäystä. Tulostus: Korjaa T:n puna-mustaksi. RBT_LISÄYS_KORJAUS(T,z) 1. while z.p.color == RED 2. if z.p == z.p.p.left 3. L_KORJAA_VASEN(T,z) 4. else 5. L_KORJAA_OIKEA(T,z) 6. T.root.color = BLACK L_KORJAA_VASEN(T,z) 1. y = z.p.p.right 2. if y.color == RED 3. z.p.color = BLACK 4. y.color = BLACK 5. z.p.p.color = RED 6. z = z.p.p 7. else 8. if z == z.p.right 9. z = z.p 10. RBT_VASEN_ROTAATIO(T,z) 11. z.p.color = BLACK 12. z.p.p.color = RED 13. RBT_OIKEA_ROT...(T,z.p.p) Oikea puoli korjataan vastaavasti 56
IV.5.2.3 Puna-mustasta puusta poistaminen: apualgoritmi Syöte: Puna-musta puu T ja sen solmu u sekä solmu v. Tulostus: Poistaa puusta u:n ja siitä lähtevän alipuun ja korvaa tämän solmulla v ja siitä lähtevällä alipuulla. RBT_TRANSPLANT(T,u,v) 1. if u.p == NIL 2. T.root = v 3. else 4. if u == u.p.left 5. u.p.left = v 6. else 7. u.p.right = v 8. v.p = u.p 811312A TRA, Perustietorakenteet 57
IV.5.2.3 Puna-mustasta puusta poistaminen (2) Syöte: Puna-musta puu T ja sen solmu z. Tulostus: Poistaa puusta solmun z niin, että jäljelle jää puna-musta puu. RBT_POISTA(T,z) 1. y = z 2. y_orig_color = y.color 3. if z.left == NIL 4. x = z.right 5. RBT_TRANSPLANT(T,z,z.right) 6. else 7. if z.right == NIL 8. x = z.left 9. RBT_TRANSPLANT(T,z,z.left) 10. else 11. y = BST_MINIMI(z.right) 12. y_orig_color = y.color 13. x = y.right 14. if y.p == z 15. x.p = y 16. else 17. RBT_TRANSPLANT(T,y, y.right) 18. y.right = z.right 19. y.right.p = y 20. RBT_TRANSPLANT(T,z,y) 21. y.left = z.left 22. y.left.p = y 23. y.color = z.color 24. if y_orig_color == BLACK 25. RBT_POISTO_KORJAUS(T,x) 58
IV.5.2.3 Puna-mustasta puusta poistaminen (3) Syöte: Puu T ja solmu x. Tulostus: Korjaa T:n punamustaksi. RBT_POISTO_KORJAUS(T,x) 1. while x!= T.root && x.color == BLACK 2. if x == x.p.left 3. P_KORJAA _VASEN(T,x) 4. else 5. P_KORJAA_OIKEA(T,x) 6. x.color = BLACK P_KORJAA_VASEN(T,x) 1. w = x.p.right 2. if w.color == RED 3. w.color = BLACK 4. x.p.color = RED 5. RBT_VASEN_ROTAATIO(T, x.p) 6. w = x.p.right 7. if w.left.color == BLACK && w.right.color == BLACK 8. w.color = RED 9. x = x.p 10. else 11. if w.right.color == BLACK 12. w.left.color = BLACK 13. w:color = RED 14. RBT_OIKEA_ROTAATIO(T,w) 15. w = x.p.right 16. w.color = x.p.color 17. x.p.color = BLACK 18. w.right.color = BLACK 19. RBT_VASEN_ROTAATIO(T,x.p) 20. x = T.root Oikea puoli korjataan vastaavasti 59
IV.5.2.4 Puna-mustan puun operaatioiden kompleksisuus Oletetaan: puussa n avainta ja puun korkeus h Lisäysalgoritmissa askelittain puussa syvemmälle, lopuksi korjaus, joka tekee samoin (rotaatiot vakioaikaisia) -> operaatio luokkaa O(h) ja siten O(lg(n)) Poisto: RBT_TRANSPLANT vakioaikainen, rotaatiot vakioaikaisia BST_MINIMI luokkaa O(h), samoin korjaus -> operaatio luokkaa O(h) ja siten O(lg(n)) 811312A TRA, Perustietorakenteet 60
IV.6 Tietorakenteiden täydentäminen Ohjelman suunnittelussa kohdataan usein tilanteita, joissa valmiit tietorakenteet eivät sellaisenaan sovellu Kehitettävä ratkaisuun soveltuva uusi tietorakenne Harvoin tarpeellista Muokattava olemassa olevaa tietorakennetta lisätiedolla ja uusilla operaatioilla Riittää useimmin Ei aina ihan helppoa, koska tietorakenteen operaatioita voidaan joutua muuttamaan 811312A TRA, Perustietorakenteet 61
IV.6.1 Esimerkki: Järjestystunnusluvut A järjestämätön joukko jossa n alkiota. Joukon A i:s järjestystunnusluku on sen i:nneksi pienin alkio. Jos joukon A i:s järjestystunnusluku on x, niin alkion x järjestysluku (rank) joukossa A on i. 811312A TRA, Perustietorakenteet 62
IV.6.1. Esimerkki: Järjestystunnusluvut (2) Laadittava ohjelma, jossa joukosta löydetään tehokkaasti i:s järjestysluku Voidaan hakea järjestämättömästä taulukosta ajassa O(n), kun taulukossa n alkiota Rekursiivisesti jakamalla taulukkoa kuten QUICKSORT-algoritmissa Pyritään parempaan tehokkuuteen Valitaan tietorakenteeksi järjestystunnuspuu: Punamusta puu, jossa solmuun lisätty kenttä size, joka kertoo kyseisen solmun määrittämässä alipuussa sijaitsevien sisäsolmujen lukumäärän mukaan lukien solmu itse 811312A TRA, Perustietorakenteet 63
IV.6.1.1 Järjestystunnuspuu 811312A TRA, Perustietorakenteet 64
IV.6.1.2 Järjestystunnusluvun hakeminen Syöte: Järjestystunnuspuun solmu x ja luku i Tulostus: Palauttaa osoittimen solmuun, joka sisältää i:nneksi pienimmän luvun solmun x määrittämässä alipuussa 1. OS_SELECT(x,i) 2. r = x.left.size+1 3. if i == r 4. return x 5. else if i < r 6. return OS_SELECT(x.left,i) 7. else 8. return OS_SELECT(x.right, i-r) 811312A TRA, Perustietorakenteet 65
IV.6.1.3 Solmun järjestysluvun hakeminen Syöte: Järjestystunnuspuu T ja sen solmu x Tulostus: Palauttaa solmun x järjestysluvun 1. OS_RANK(T,x) 2. r = x.left.size + 1 3. y = x 4. while y!= T.root 5. if y == y.p.right 6. r = r + y.p.left.size + 1 7. y = y.p 8. return r 811312A TRA, Perustietorakenteet 66
IV.6.1.4 Operaatioiden analyysi Varmista, että OS_SELECT ja OS_RANK korrekteja! OS_SELECT jokaisella rekursiivisella kutsulla syvemmälle puuhun -> kompleksisuus luokkaa Ɵ(h) missä h on puun korkeus OS_RANK jokaisella silmukan kierroksella ylemmäksi puussa -> kompleksisuus luokkaa Ɵ(h) missä h on puun korkeus Koska puna-musta puu, niin kompleksisuus luokkaa Ɵ(lg(n)), missä n solmujen lukumäärä 811312A TRA, Perustietorakenteet 67
IV.6.1.5 Muutokset puna-mustan puun toimintoihin Avaimen etsiminen, minimi ja maksimi voidaan hakea entiseen tapaan Avaimen lisääminen ja poistaminen muutettava niin että kenttä size pysyy oikeana Muutetaan aluksi rotaatiot tukemaan kenttää size Vasempaan rotaatioon solmujen päivitys RBT_VASEN_ROTAATIO(T,x) 1. y = x.right 2.-13. // Kuten ennen 14. y.size = x.size 15. x.size = x.left.size+x.right.size+1 16. return 811312A TRA, Perustietorakenteet 68
IV.6.1.5 Muutokset puna-mustan puun toimintoihin (2) Oikeaan rotaatioon solmujen päivitys RBT_OIKEA_ROTAATIO(T,x) 1. y = x.left 2.-13. // Kuten ennen 14. y.size = x.size 15. x.size = x.left.size+x.right.size+1 16. return 811312A TRA, Perustietorakenteet 69
IV.6.1.5 Muutokset puna-mustan puun toimintoihin: Lisäys Lisättävän solmun size-kenttään arvo 1 Lisättäessä lehden hakupolulla kasvatetaan kaikkien solmujen kenttää arvolla 1 -> size-kentät oikeat kun solmu lehdessä Rotaatioilla puna-mustaominaisuus kuntoon -> Kun sovelletaan muutettua rotaatiota, myös size-kentät pysyvät kunnossa Operaation kompleksisuus säilyy samana, on ts. Ɵ(lg(n)), missä n solmujen lukumäärä 811312A TRA, Perustietorakenteet 70
IV.6.1.5 Muutokset puna-mustan puun toimintoihin: Poistaminen Jos poistettavalla solmulla ei ole kahta alipuuta, voidaan ensin vähentää solmusta juureen kulkevassa polussa kaikkien solmujen size-kenttää arvolla 1. Tämän jälkeen solmu poistetaan Jos poistettavalla solmulla on kaksi alipuuta haetaan oikealta minimisolmu ja vähennetään minimisolmusta juureen kulkevassa polussa kaikkien solmujen sizekenttää arvolla 1. Tämän jälkeen solmu poistetaan Rotaatioilla puna-mustaominaisuus kuntoon -> muutetuilla rotaatioilla myös size-kentät kunnossa Operaation kompleksisuus säilyy samana, on ts. Ɵ(lg(n)), missä n solmujen lukumäärä 811312A TRA, Perustietorakenteet 71
IV.6.2. Tietorakenteen täydentämisen formalismi 1. Alla olevan tietorakenteen valinta Esimerkissä puna-musta puu 2. Täydentämisen kautta lisättävän informaation tarkka määrittely Esimerkissä solmujen size-kenttä 3. Uuden informaation oikean käsittelyn verifiointi tietorakenteen perusoperaatioille Esimerkissä size-kentän ylläpito lisättäessä ja poistettaessa 4. Uusien operaatioiden kehittäminen Esimerkissä OS_SELECT ja OS_RANK 811312A TRA, Perustietorakenteet 72