Symbolitaulut Joukko hakuavaimen omaavia tietueita LISÄÄ uusi tietue ETSI tietue hakuavaimen perusteella Sovelluksia: Spell checker etsii sanoja sanakirjasta Kääntäjä etsii muuttujien nimet Internet domain server etsii IP osoitteen
Symbolitaulun operaatiot Tietueen lisääminen Tietueen hakeminen avaimen perusteella Symbolitaulun alustaminen Tietueen poisto symbolitaulusta k:nen alkion valinta Symbolitaulun lajittelu Kahden symbolitaulun liittäminen yhteen typedef int avain; typedef struct { avain ID; char nimi[30]; } alkio; avain = opiskelijanumero alkio = op.no + nimi
Symbolitaulun operaatiot Tietueen lisääminen Tietueen hakeminen avaimen perusteella Symbolitaulun alustaminen Tietueen poisto symbolitaulusta k:nen alkion valinta Symbolitaulun lajittelu Kahden symbolitaulun liittäminen yhteen typedef char *avain; typedef struct { avain url; int laskuri; } alkio; avain = URL alkio = URL + laskuri
Symbolitaulu: toteutus lajittemattomalla taulukolla LISÄÄ: Tietue lisätään taulukon loppuun avain = alkio = int HAKU: Jokaista taulukon avainta verrataan hakuavaimeen kunnes haluttu sana löytyy tai taulukko on käyty läpi
Symbolitaulu: toteutus lajittellulla taulukolla LISÄÄ: Etsitään lisäyskohta ja siirretään alkioita oikealle avain = alkio = int BINÄÄRIHAKU: Verrataan taulukon keskimmäiseen avaimeen Mikäli samat => haku päättyy Muussa tapauksessa etsitään joko vasemmalta tai oikealta 6
Binäärihaun eteneminen AAACEEEGHILMNPR HILMNPR HIL L Tarvitaan kolme iteraatiota L:n löytämiseksi 1. Verrataan hakuavainta L keskimmäiseen alkioon G, koska L on isompi seuraava iteraatio käyttää G:n oikean puoleisia arvoja 2. L on pienempi kuin M => kolmas iteraatio suoritetaan H,I,L alkioille Yhden lisäiteraation jälkeen koko on 1 ja L löytyy
Binäärihaku alkio hae(int l, int r, Avain v) { int m = (l + r) / 2; /* puolivälin laskenta */ if(l > r) /* jos ei voi enää löytyä */ { return NULLalkio; } if(YHTASUURI(v, AVAIN(st[m]))) { return st[m]; } if(l == r) /* jos ei voi enää löytyä */ { return NULLalkio; } if(PIENEMPI(v, AVAIN(st[m]))) /* jos haettava pienempi */ { return hae(l, m – 1, v); /* haetaan alkupuolikkaasta */ } else { return hae(m + 1, r, v); /* haetaan loppupuolikkaasta */ } } #define NULLalkio -1 typedef int alkio; typedef int avain; #define AVAIN(A) (A) #define YHTASUURI(A, B) (!PIENEMPI(A, B) && !PIENEMPI(B, A)) #define PIENEMPI(A, B) (AVAIN(A) < AVAIN(B)) static alkio *st;
Symbolitaulu: toteutus kustannukset HakuLisäysPoistoHakuLisäysPoisto N11N/211 lg NNN N/2 Toteutus Lajittelematon taulukko Lajiteltu taulukko, binäärihaku Huonoin tapausKeskimääräinen tapaus
Binääriset hakupuut Lisäykset järjestettyyn taulukkoon olivat laskennallisesti raskaita Käytetään ekplisiittistä puurakennetta x solmu AB alipuut pienempiäsuurempia
Binäärinen hakupuu C-kielellä linkki on osoitin solmuun Solmu koostuu kolmesta kentästä Avaimellisesta solmusta Vasen linkki (binääripuu, jossa pienemmät avaimet) Oikea linkki (binääripuu, jossa suuremmat avaimet) typedef struct STsolmu* linkki; struct STsolmu { alkio item; linkki l, r; }; static linkki paa, z;
Haku binäärisestä hakupuusta alkio haeR(linkki h, Avain v) { avain t = AVAIN(h->item); if(h == z) { return NULLalkio; } if(YHTASUURI(v, t)) { return h->item; } if(PIENEMPI(v, t)) { return haeR(h->l, v); } else { return haeR(h->r, v); } } alkio SThae(Avain v) { return haeR(paa, v); } Etsitään avainta v Koodi seuraa suoraan binääripuun määritelmästä
Lisäys binääriseen hakupuuhun linkki lisaaR(linkki h, alkio item) { Avain v = AVAIN(item), t = AVAIN(h->item); if(h == z) { return uusi(item, z, z, 1); } if(PIENEMPI(v, t)) { h->l = lisaaR(h->l, item); } else { h->r = lisaaR(h->r, item); } (h->n)++; /* solmujen lukumäärä alipuussa */ return h; } void STlisaa(alkio item) { paa = lisaaR(paa, item); } Lisätään alkio Ensin etsitään, sitten lisätään
Binäärisen hakupuun rakentaminen Lisätään avaimet: H A K U E S I M H
Binäärisen hakupuun rakentaminen Lisätään avaimet: H A K U E S I M H A
Binäärisen hakupuun rakentaminen Lisätään avaimet: H A K U E S I M H AK
Binäärisen hakupuun rakentaminen Lisätään avaimet: H A K U E S I M H AK U
Binäärisen hakupuun rakentaminen Lisätään avaimet: H A K U E S I M H AK UE
Binäärisen hakupuun rakentaminen Lisätään avaimet: H A K U E S I M H AK U E S
Binäärisen hakupuun rakentaminen Lisätään avaimet: H A K U E S I M H AK U EI S
Binäärisen hakupuun rakentaminen Lisätään avaimet: H A K U E S I M H AK U EI S M
Muita symbolitaulun operaatioita LAJITTELU: käydään puu läpi sisäjärjestyksessä Linkit vievät muistia ETSI K:S alkio: Lisätään alipuun koko jokaiseen solmuun T W YV H M E B F P
Muita symbolitaulun operaatioita: poistaminen Ei lapsia E I M => poista Yksi lapsi A U S => lapsi ylöspäin Kaksi lasta H K - etsi seuraavaksi suurin lapsi - vaihda - poista kuten yllä, koska sillä on nyt 0 tai 1 lasta H AK U EI S M
Kierto vasemmalle, kierto oikealle Perustava operaatio solmujen uudelleenjärjestämiseksi puussa Säilyttää binääripuu ominaisuuden Paikallisia muunnoksia, vaihdetaan 3 osoitinta x A CB y y A C B x juuri kierto vasemmalle
Kierto vasemmalle, kierto oikealle Perustava operaatio solmujen uudelleenjärjestämiseksi puussa Säilyttää binääripuu ominaisuuden Paikallisia muunnoksia, vaihdetaan 3 osoitinta x A CB y y A C B x juuri kierto oikealle
Kierto oikealle linkki kiertoO(linkki h) { linkki x = h->l; /* kiertosolmun vasen lapsi */ h->l = x->r; x->r = h; return x; } A E C S X R H GI Kierto oikealle solmun S suhteen
Kierto oikealle linkki kiertoO(linkki h) { linkki x = h->l; /* kiertosolmun vasen lapsi */ h->l = x->r; x->r = h; return x; } A E C S X R H GI Kierto oikealle solmun S suhteen
Kierto oikealle linkki kiertoO(linkki h) { linkki x = h->l; /* kiertosolmun vasen lapsi */ h->l = x->r; x->r = h; return x; } A E C S X R H GI Kierto oikealle solmun S suhteen
Kierto oikealle linkki kiertoO(linkki h) { linkki x = h->l; /* kiertosolmun vasen lapsi */ h->l = x->r; x->r = h; return x; } A E C S X R H GI Kierto oikealle solmun S suhteen
Kierto vasemmalle linkki kiertoV(linkki h) { linkki x = h->r; /* kiertosolmun oikea lapsi */ h->r = x->l; x->l = h; return x; } A E C S X R H GI Kierto vasemmalle solmun A suhteen
Kierto vasemmalle linkki kiertoV(linkki h) { linkki x = h->r; /* kiertosolmun oikea lapsi */ h->r = x->l; x->l = h; return x; } A C S X R H GI Kierto vasemmalle solmun A suhteen E
Kierto vasemmalle linkki kiertoV(linkki h) { linkki x = h->r; /* kiertosolmun oikea lapsi */ h->r = x->l; x->l = h; return x; } A C S X R H GI Kierto vasemmalle solmun A suhteen E
Kierto vasemmalle linkki kiertoV(linkki h) { linkki x = h->r; /* kiertosolmun oikea lapsi */ h->r = x->l; x->l = h; return x; } A C S X R H GI Kierto vasemmalle solmun A suhteen E
Lisäys binäärisen hakupuun juureen Lisäys juureen: lisää solmu ja tee siitä juurisolmu Lisää solmu kuten tavallisessa binäärihakupuussa Käytä kiertoja sen tuomiseksi juureen Miksi vaivautua ? Nopeampi jos haut tapahtuvat viimeksi lisättyihin avaimiin Muodostaa pohjan edistyneimmille algoritmeille
Lisäys binäärisen hakupuun juureen linkki lisaaT(linkki h, alkio item) { Avain v = AVAIN(item); if(h == z) /* jos lehtisolmu */ { return uusi(item, z, z, 1); } if(PIENEMPI(v, AVAIN(h->item))) { h->l = lisaaT(h->l, item); /* vasemmalle */ h = kiertoO(h); /* kierto oikealle */ } else { h->r = lisaaT(h->r, item); /* oikealle */ h = kiertoV(h); /* kierto vasemmalle */ } return h; } void STlisaa(alkio item) { paa = lisaaT(paa, item); } A S X E C R H lisätään g
Lisäys binäärisen hakupuun juureen linkki lisaaT(linkki h, alkio item) { Avain v = AVAIN(item); if(h == z) /* jos lehtisolmu */ { return uusi(item, z, z, 1); } if(PIENEMPI(v, AVAIN(h->item))) { h->l = lisaaT(h->l, item); /* vasemmalle */ h = kiertoO(h); /* kierto oikealle */ } else { h->r = lisaaT(h->r, item); /* oikealle */ h = kiertoV(h); /* kierto vasemmalle */ } return h; } void STlisaa(alkio item) { paa = lisaaT(paa, item); } A S X E C R H lisätään g
Lisäys binäärisen hakupuun juureen linkki lisaaT(linkki h, alkio item) { Avain v = AVAIN(item); if(h == z) /* jos lehtisolmu */ { return uusi(item, z, z, 1); } if(PIENEMPI(v, AVAIN(h->item))) { h->l = lisaaT(h->l, item); /* vasemmalle */ h = kiertoO(h); /* kierto oikealle */ } else { h->r = lisaaT(h->r, item); /* oikealle */ h = kiertoV(h); /* kierto vasemmalle */ } return h; } void STlisaa(alkio item) { paa = lisaaT(paa, item); } A S X E C R H lisätään g
Lisäys binäärisen hakupuun juureen linkki lisaaT(linkki h, alkio item) { Avain v = AVAIN(item); if(h == z) /* jos lehtisolmu */ { return uusi(item, z, z, 1); } if(PIENEMPI(v, AVAIN(h->item))) { h->l = lisaaT(h->l, item); /* vasemmalle */ h = kiertoO(h); /* kierto oikealle */ } else { h->r = lisaaT(h->r, item); /* oikealle */ h = kiertoV(h); /* kierto vasemmalle */ } return h; } void STlisaa(alkio item) { paa = lisaaT(paa, item); } A S X E C R H lisätään g
Lisäys binäärisen hakupuun juureen linkki lisaaT(linkki h, alkio item) { Avain v = AVAIN(item); if(h == z) /* jos lehtisolmu */ { return uusi(item, z, z, 1); } if(PIENEMPI(v, AVAIN(h->item))) { h->l = lisaaT(h->l, item); /* vasemmalle */ h = kiertoO(h); /* kierto oikealle */ } else { h->r = lisaaT(h->r, item); /* oikealle */ h = kiertoV(h); /* kierto vasemmalle */ } return h; } void STlisaa(alkio item) { paa = lisaaT(paa, item); } A S X E C R H lisätään g
Lisäys binäärisen hakupuun juureen linkki lisaaT(linkki h, alkio item) { Avain v = AVAIN(item); if(h == z) /* jos lehtisolmu */ { return uusi(item, z, z, 1); } if(PIENEMPI(v, AVAIN(h->item))) { h->l = lisaaT(h->l, item); /* vasemmalle */ h = kiertoO(h); /* kierto oikealle */ } else { h->r = lisaaT(h->r, item); /* oikealle */ h = kiertoV(h); /* kierto vasemmalle */ } return h; } void STlisaa(alkio item) { paa = lisaaT(paa, item); } A S X E C R H lisätään g G
Lisäys binäärisen hakupuun juureen linkki lisaaT(linkki h, alkio item) { Avain v = AVAIN(item); if(h == z) /* jos lehtisolmu */ { return uusi(item, z, z, 1); } if(PIENEMPI(v, AVAIN(h->item))) { h->l = lisaaT(h->l, item); /* vasemmalle */ h = kiertoO(h); /* kierto oikealle */ } else { h->r = lisaaT(h->r, item); /* oikealle */ h = kiertoV(h); /* kierto vasemmalle */ } return h; } void STlisaa(alkio item) { paa = lisaaT(paa, item); } A S X E C R H lisätään g G
Lisäys binäärisen hakupuun juureen linkki lisaaT(linkki h, alkio item) { Avain v = AVAIN(item); if(h == z) /* jos lehtisolmu */ { return uusi(item, z, z, 1); } if(PIENEMPI(v, AVAIN(h->item))) { h->l = lisaaT(h->l, item); /* vasemmalle */ h = kiertoO(h); /* kierto oikealle */ } else { h->r = lisaaT(h->r, item); /* oikealle */ h = kiertoV(h); /* kierto vasemmalle */ } return h; } void STlisaa(alkio item) { paa = lisaaT(paa, item); } A S X E C R H lisätään g G BA C x y B A C y x
Lisäys binäärisen hakupuun juureen linkki lisaaT(linkki h, alkio item) { Avain v = AVAIN(item); if(h == z) /* jos lehtisolmu */ { return uusi(item, z, z, 1); } if(PIENEMPI(v, AVAIN(h->item))) { h->l = lisaaT(h->l, item); /* vasemmalle */ h = kiertoO(h); /* kierto oikealle */ } else { h->r = lisaaT(h->r, item); /* oikealle */ h = kiertoV(h); /* kierto vasemmalle */ } return h; } void STlisaa(alkio item) { paa = lisaaT(paa, item); } A S X E C R G lisätään g H BA C x y B A C y x
Lisäys binäärisen hakupuun juureen linkki lisaaT(linkki h, alkio item) { Avain v = AVAIN(item); if(h == z) /* jos lehtisolmu */ { return uusi(item, z, z, 1); } if(PIENEMPI(v, AVAIN(h->item))) { h->l = lisaaT(h->l, item); /* vasemmalle */ h = kiertoO(h); /* kierto oikealle */ } else { h->r = lisaaT(h->r, item); /* oikealle */ h = kiertoV(h); /* kierto vasemmalle */ } return h; } void STlisaa(alkio item) { paa = lisaaT(paa, item); } A S X E C R G lisätään g H BA C x y B A C y x
Lisäys binäärisen hakupuun juureen linkki lisaaT(linkki h, alkio item) { Avain v = AVAIN(item); if(h == z) /* jos lehtisolmu */ { return uusi(item, z, z, 1); } if(PIENEMPI(v, AVAIN(h->item))) { h->l = lisaaT(h->l, item); /* vasemmalle */ h = kiertoO(h); /* kierto oikealle */ } else { h->r = lisaaT(h->r, item); /* oikealle */ h = kiertoV(h); /* kierto vasemmalle */ } return h; } void STlisaa(alkio item) { paa = lisaaT(paa, item); } A S X E C G R lisätään g H BA C x y B A C y x
Lisäys binäärisen hakupuun juureen linkki lisaaT(linkki h, alkio item) { Avain v = AVAIN(item); if(h == z) /* jos lehtisolmu */ { return uusi(item, z, z, 1); } if(PIENEMPI(v, AVAIN(h->item))) { h->l = lisaaT(h->l, item); /* vasemmalle */ h = kiertoO(h); /* kierto oikealle */ } else { h->r = lisaaT(h->r, item); /* oikealle */ h = kiertoV(h); /* kierto vasemmalle */ } return h; } void STlisaa(alkio item) { paa = lisaaT(paa, item); } A S X E C G R lisätään g H BA C x y B A C y x
Lisäys binäärisen hakupuun juureen linkki lisaaT(linkki h, alkio item) { Avain v = AVAIN(item); if(h == z) /* jos lehtisolmu */ { return uusi(item, z, z, 1); } if(PIENEMPI(v, AVAIN(h->item))) { h->l = lisaaT(h->l, item); /* vasemmalle */ h = kiertoO(h); /* kierto oikealle */ } else { h->r = lisaaT(h->r, item); /* oikealle */ h = kiertoV(h); /* kierto vasemmalle */ } return h; } void STlisaa(alkio item) { paa = lisaaT(paa, item); } A S X E C G R lisätään g H BA C x y B A C y x
Lisäys binäärisen hakupuun juureen linkki lisaaT(linkki h, alkio item) { Avain v = AVAIN(item); if(h == z) /* jos lehtisolmu */ { return uusi(item, z, z, 1); } if(PIENEMPI(v, AVAIN(h->item))) { h->l = lisaaT(h->l, item); /* vasemmalle */ h = kiertoO(h); /* kierto oikealle */ } else { h->r = lisaaT(h->r, item); /* oikealle */ h = kiertoV(h); /* kierto vasemmalle */ } return h; } void STlisaa(alkio item) { paa = lisaaT(paa, item); } A S X E C G R lisätään g H BA C x y B A C y x
Lisäys binäärisen hakupuun juureen linkki lisaaT(linkki h, alkio item) { Avain v = AVAIN(item); if(h == z) /* jos lehtisolmu */ { return uusi(item, z, z, 1); } if(PIENEMPI(v, AVAIN(h->item))) { h->l = lisaaT(h->l, item); /* vasemmalle */ h = kiertoO(h); /* kierto oikealle */ } else { h->r = lisaaT(h->r, item); /* oikealle */ h = kiertoV(h); /* kierto vasemmalle */ } return h; } void STlisaa(alkio item) { paa = lisaaT(paa, item); } A S X E C G R lisätään g H BA C x y B A C y x
Lisäys binäärisen hakupuun juureen linkki lisaaT(linkki h, alkio item) { Avain v = AVAIN(item); if(h == z) /* jos lehtisolmu */ { return uusi(item, z, z, 1); } if(PIENEMPI(v, AVAIN(h->item))) { h->l = lisaaT(h->l, item); /* vasemmalle */ h = kiertoO(h); /* kierto oikealle */ } else { h->r = lisaaT(h->r, item); /* oikealle */ h = kiertoV(h); /* kierto vasemmalle */ } return h; } void STlisaa(alkio item) { paa = lisaaT(paa, item); } A S X E C G R lisätään g H BA C x y B A C y x
Lisäys binäärisen hakupuun juureen linkki lisaaT(linkki h, alkio item) { Avain v = AVAIN(item); if(h == z) /* jos lehtisolmu */ { return uusi(item, z, z, 1); } if(PIENEMPI(v, AVAIN(h->item))) { h->l = lisaaT(h->l, item); /* vasemmalle */ h = kiertoO(h); /* kierto oikealle */ } else { h->r = lisaaT(h->r, item); /* oikealle */ h = kiertoV(h); /* kierto vasemmalle */ } return h; } void STlisaa(alkio item) { paa = lisaaT(paa, item); } A S X E C G R lisätään g H BA C x y B A C y x
Symbolitaulu: toteutus kustannukset HakuLisäysPoistoHakuLisäysPoisto N11N/211 lg NNN N/2 NNNlog N NN Toteutus Lajittelematon taulukko Lajiteltu taulukko, binäärihaku Binääripuu Huonoin tapausKeskimääräinen tapaus