811312A Tietorakenteet ja algoritmit 2018-2019 V Hash-taulukot ja binääriset etsintäpuut
Sisältö 1. Hash-taulukot 2. Binääriset etsintäpuut 811312A TRA, Hash-taulukot, binääripuut 2
V.1 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, Hash-taulukot, binääripuut 3
V.1 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, Hash-taulukot, binääripuut 4
V.1.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, Hash-taulukot, binääripuut 5
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
V.1.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, Hash-taulukot, binääripuut 7
V.1.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, Hash-taulukot, binääripuut 8
V.1.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, Hash-taulukot, binääripuut 9
V.1.3. Erilaisia tiivistefunktioita (2) Tulomenetelmä: h( k) m ( ka(mod 1)) A jokin reaalilukuvakio 0 < A < 1 Etu: Ei riipu kriittisesti luvusta m 811312A TRA, Hash-taulukot, binääripuut 10
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)
V.1.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, Hash-taulukot, binääripuut 12
V.1.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, Hash-taulukot, binääripuut 13
V.1.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, Hash-taulukot, binääripuut 14
V.1.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, Hash-taulukot, binääripuut 15
V.1.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, Hash-taulukot, binääripuut 16
V.1.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, Hash-taulukot, binääripuut 17
V.1.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, Hash-taulukot, binääripuut 18
V.1.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, Hash-taulukot, binääripuut 19
V.2 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, Hash-taulukot, binääripuut 20
V.2 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, Hash-taulukot, binääripuut 21
Esimerkki binäärisestä hakupuusta 20 10 28 8 16 27 14 18 811312A TRA, Hash-taulukot, binääripuut 22
V.2.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, Hash-taulukot, binääripuut 23
V.2.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, Hash-taulukot, binääripuut 24
V.2.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, Hash-taulukot, binääripuut 25
V.2.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 26
V.2.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, Hash-taulukot, binääripuut 27
V.2.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, Hash-taulukot, binääripuut 28
V.2.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, Hash-taulukot, binääripuut 29
V.2.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, Hash-taulukot, binääripuut 30
V.2.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) 31
V.2.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, Hash-taulukot, binääripuut 32