Algoritmit 2 Luento 2 To 14.3.2019 Timo Männikkö
Luento 2 Tietorakenteet Lineaarinen lista, binääripuu Prioriteettijono Kekorakenne Keko-operaatiot Keon toteutus taulukolla Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 2/29
Tietorakenteet Algoritmin toteutus vaatii sopivan tietorakenteen Ongelman tiedot, algoritmin tiedot, työtilat Tallennustapa vaikuttaa suoritusaikaan ja muistitilan tarpeeseen Tarkastellaan tietorakenteita abstrakteina tietotyyppeinä Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 3/29
Abstrakti tietotyyppi Tiedot: Mitä tietoalkioita rakenteessa on Operaatiot: Mitä tiedoilla voidaan tehdä Riippumaton tiedon esitysmuodosta ja toteutuksen ohjelmointikielestä Ei välitetä toteutuksen yksityiskohdista Erilaiset määrittelyt ja toteutukset vaikuttavat algoritmin toimintaan: Nopeus, muistitila, yksinkertaisuus, käytettävyys jne. Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 4/29
Lineaarinen lista Toteutus esimerkiksi dynaamisesti linkitettynä listana Listaosoitin ainakin ensimmäiseen alkioon Mahdollisesti muita osoittimia, linkkejä, alkutietueita jne. Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 5/29
Listan operaatiot Järjestämätön lista: Alkiot eivät erityisessä järjestyksessä Lisäys: Esimerkiksi listan alkuun Θ(1) Poisto: Poistettava alkio etsitään Θ(n) Järjestetty lista: Alkiot avainkentän mukaan järjestyksessä Lisäys: Lisäyksen paikka etsitään Θ(n) Poisto: Poistettava alkio etsitään Θ(n) (Tai esimerkiksi binäärihaku Θ(log n)) Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 6/29
Binääripuu vasemman alipuun juurisolmu puun juurisolmu oikean alipuun juurisolmu 7 7 Järjestetty binääripuu: Vasemman alipuun solmut Alipuun juurisolmu Oikean alipuun solmut Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 7/29
Binääripuun operaatiot Hakupolku: Aloitetaan puun juurisolmusta Edetään vasempaa tai oikeaan alipuuhun Pahimmassa tapauksessa jatketaan johonkin lehtisolmuun saakka Lisäys ja poisto: Hakupolun pituus Puun korkeus Tasapainoinen puu Θ(log n) Degeneroitunut puu Θ(n) Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 8/29
Prioriteettijono Kokoelma alkioita, joihin liittyy jokin arvo, prioriteetti (paino) Lisää alkio -operaatio Poista pienin -operaatio Palautetaan ja poistetaan alkio, jolla pienin prioriteetti Palauttaminen ja poistaminen voidaan toteuttaa myös kahtena eri operaationa Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 9/29
Prioriteettijono Prioriteettien ei tarvitse olla erisuuruisia Silloin täytyy määritellä prioriteettijonon stabiilisuus eli mikä alkio poistetaan yhtäsuurien prioriteettien tapauksessa Muita mahdollisia operaatioita: isempty: Testaa onko prioriteettijono tyhjä size: Palauttaa prioriteettijonon alkioiden lukumäärän Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 10/29
Prioriteettijono Poista pienin Minimiprioriteettijono Poista suurin Maksimiprioriteettijono Jatkossa kaikki prioriteettijonot ovat minimiprioriteettijonoja (ellei toisin mainittu) Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 11/29
Prioriteettijonon toteutus Järjestämätön lineaarinen lista: Lisäys Θ(1) Poisto Θ(n) Järjestetty lineaarinen lista: Lisäys Θ(n) Poisto Θ(1) Järjestetty binääripuu (binäärinen hakupuu): Lisäys ja poisto Θ(log n) Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 12/29
Kekorakenne Keko (heap) on binääripuu, joka on Osittain järjestetty: Jokaisen solmun prioriteetti ei ole suurempi kuin sen lapsisolmujen prioriteetit Melkein täydellinen: Tasoilla 0, 1,..., h 1 niin monta solmua kuin mahdollista ja alimmalla tasolla h kaikki solmut niin vasemmalla kuin mahdollista Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 13/29
Esimerkki 5 9 7 7 15 18 8 21 16 30 22 7 Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 14/29
Kekorakenne Tasolla i (paitsi alimmalla) on 2 i solmua Korkeintaan yksi solmu, jolla on yksi lapsi ja tämä lapsi on vanhempansa vasen lapsi Jos solmut käydään läpi rakenteellisessa järjestyksessä (sisäjärjestyksessä) Lehtisolmut käydään läpi siten, että ensin käydään kaikissa alimman tason h lehtisolmuissa ja niiden jälkeen tason h 1 lehtisolmuissa Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 15/29
Lisäys kekoon Säilytetään melkein täydellinen rakenne: Jos lehtisolmuja kahdella tasolla Uusi solmu alimmalle tasolle mahdollisimman vasemmalle Jos lehtisolmuja yhdellä tasolla Uusi solmu vasemmanpuoleisimman (rakenteellisessa järjestyksessä ensimmäisen) solmun vasemmaksi lapseksi Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 16/29
Lisäys kekoon jatkuu Osittainen järjestys kuntoon: Jos lisätyn solmun prioriteetti ei ole pienempi kuin sen vanhemman prioriteetti, osittainen järjestys on kunnossa Muuten vaihdetaan solmun ja sen vanhemman sisällöt keskenään Toistetaan solmun ja sen vanhemman prioriteettien vertailua ja jatketaan, kunnes osittainen järjestys kunnossa Tarvittaessa toistetaan aina juurisolmuun saakka Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 17/29
Poisto keosta Poistettava solmu on juurisolmu Säilytetään melkein täydellinen rakenne: Poistetaan alimman tason oikeanpuoleisin solmu Sijoitetaan se juurisolmun tilalle Jos poistoon sisältyy palautus: Juurisolmun sisältö otetaan talteen ennen kuin se korvataan toisella solmulla Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 18/29
Poisto keosta jatkuu Osittainen järjestys kuntoon: Jos uuden juurisolmun prioriteetti ei ole suurempi kuin sen lapsisolmujen prioriteetit, osittainen järjestys on kunnossa Muuten vaihdetaan solmun ja sen pienemmän lapsen sisällöt keskenään Toistetaan solmun ja sen lapsien prioriteettien vertailua ja jatketaan, kunnes osittainen järjestys kunnossa Tarvittaessa toistetaan aina johonkin lehtisolmuun saakka Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 19/29
Keko-operaatioiden vaativuus Pahimmassa tapauksessa käydään läpi polku juurisolmusta johonkin lehtisolmuun (jompaankumpaan suuntaan) Keko melkein täydellinen, joten sen korkeus kertaluokkaa Θ(log n) Operaatioiden aikavaativuus Θ(log n) Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 20/29
Keon toteutus dynaamisesti Täytyy kulkea sekä juuresta lehtisolmuihin että lehtisolmuista juureen Jokaiseen solmuun tarvitaan kolme osoitinta: Osoitin vasempaan lapseen Osoitin oikeaan lapseen Osoitin vanhempaan Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 21/29
Keon toteutus taulukolla Tallennetaan solmut taulukkoon tasoittain järjestyksessä: Juurisolmu paikkaan 1 Tason 1 solmut paikkoihin 2 ja 3 Tason 2 solmut paikkoihin 4, 5, 6 ja 7 Jne. Kullakin tasolla solmut järjestyksessä vasemmalta oikealle Lisäksi paikkaan 0 tallennetaan solmujen lukumäärä Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 22/29
Keon toteutus taulukolla Yleisesti: Jos solmu taulukon paikassa i, niin Vasen lapsi paikassa 2i Oikea lapsi paikassa 2i + 1 Vanhempi paikassa i/2 Olkoon a taulukko, jonka koko on MAXPQ+1 Paikassa 0 on aina keon alkioiden lukumäärä Keon alkiot (korkeintaan MAXPQ kappaletta) on tallennettu indeksistä 1 alkaen tasoittain Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 23/29
Keko-operaatiot taulukolla lisaakekoon(int[] a, int alkio) { if (a[0] >= MAXPQ) { // Taulukko täynnä, // kasvatetaan kokoa tai heitetään poikkeus } a[0]++; int i = a[0]; // Siirretään alkiota kohti juurisolmua while ((i > 1) && (a[i/2] > alkio)) { a[i] = a[i/2]; i = i/2; } a[i] = alkio; } Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 24/29
Keko-operaatiot taulukolla korjaakeko(int[] a, int i) { if (2*i > a[0]) // i:llä ei lapsia, return; // ei tehdä mitään int j = 2*i; int alkio = a[i]; // Siirretään alkiota kohti lehtisolmuja while (j <= a[0]) { if ((j < a[0]) && (a[j] > a[j+1])) j = j+1; if (alkio <= a[j]) break; // lopetetaan silmukka a[j/2] = a[j]; j = 2*j; } a[j/2] = alkio; } Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 25/29
Keko-operaatiot taulukolla int poistapienin(int[] a) { if (a[0] == 0) { // Ei poistettavaa alkiota, // lopetetaan tai heitetään poikkeus } int alkio = a[1]; a[1] = a[a[0]]; a[0]--; korjaakeko(a, 1); return alkio; } Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 26/29
Keon muodostaminen Rakennetaan keko alkioiden syöttövaiheessa: Aluksi taulukko tyhjä (alkioiden lukumäärä 0) Kutsutaan lisaakekoon-algoritmia n kertaa Yhden lisäyksen aikavaativuus Θ(log n) Keon muodostaminen tällä tavalla Θ(n log n) Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 27/29
Keon muodostaminen Rakennetaan keko, kun kaikki alkiot syötetty: Tallennetaan alkiot taulukkoon jossain (satunnaisessa) järjestyksessä Kutsutaan korjaakeko-algoritmia toistuvasti: Aloitetaan yhden solmun keoista (lehtisolmut) Yhdistetään kekoja kunnes päädytään yhteen n:n solmun kekoon Voidaan osoittaa: Keon muodostaminen tällä tavalla Θ(n) Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 28/29
Keon muodostaminen teekeko(int[] a) // Muodostaa keon taulukkoon // tallennetuista n:stä alkiosta // a[0] sisältää alkioiden lukumäärän { for (int i = a[0]/2; i >= 1; i--) korjaakeko(a, i); } Algoritmit 2 Kevät 2019 Luento 2 To 14.3.2019 29/29