Algoritmit 2 Luento 2 Ke 15.3.2017 Timo Männikkö
Luento 2 Tietorakenteet Lineaarinen lista, binääripuu Prioriteettijono Kekorakenne Keko-operaatiot Keon toteutus taulukolla Algoritmit 2 Kevät 2017 Luento 2 Ke 15.3.2017 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 2017 Luento 2 Ke 15.3.2017 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 2017 Luento 2 Ke 15.3.2017 4/29
Lineaarinen lista Toteutus esimerkiksi dynaamisesti linkitettynä listana Listaosoitin ainakin ensimmäiseen alkioon Mahdollisesti muita linkkejä, listaosoittimia, alkutietueita jne. Algoritmit 2 Kevät 2017 Luento 2 Ke 15.3.2017 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 2017 Luento 2 Ke 15.3.2017 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 2017 Luento 2 Ke 15.3.2017 7/29
Binääripuun operaatiot Hakupolku: Aloitetaan juurisolmusta Edetään vasempaa tai oikeaan alipuuhun Pahimmassa tapauksessa jatketaan lehtisolmuun saakka Lisäys ja poisto: Askelten lukumäärä Puun korkeus Tasapainoinen puu Θ(log n) Degeneroitunut puu Θ(n) Algoritmit 2 Kevät 2017 Luento 2 Ke 15.3.2017 8/29
Prioriteettijono Kokoelma alkioita, joihin liittyy jokin arvo, prioriteetti (paino) Lisää alkio -operaatio Poista pienin -operaatio Poistetaan ja palautetaan alkio, jolla pienin prioriteetti Poistaminen ja palauttaminen voidaan toteuttaa myös kahtena eri operaationa Algoritmit 2 Kevät 2017 Luento 2 Ke 15.3.2017 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 2017 Luento 2 Ke 15.3.2017 10/29
Prioriteettijono Poista pienin Minimiprioriteettijono Poista suurin Maksimiprioriteettijono Jatkossa kaikki prioriteettijonot ovat minimiprioriteettijonoja (ellei toisin mainittu) Algoritmit 2 Kevät 2017 Luento 2 Ke 15.3.2017 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) Tavallinen binäärinen hakupuu: Lisäys ja poisto Θ(log n) Algoritmit 2 Kevät 2017 Luento 2 Ke 15.3.2017 12/29
Kekorakenne Keko (heap) on binääripuu, joka on Osittain järjestetty: Jokaisen solmun arvo (prioriteetti) ei ole suurempi kuin sen lapsisolmujen arvot Melkein täydellinen: Tasoilla 0,..., h 1 niin monta solmua kuin mahdollista ja viimeisellä tasolla h kaikki solmut niin vasemmalla kuin mahdollista Algoritmit 2 Kevät 2017 Luento 2 Ke 15.3.2017 13/29
Esimerkki 5 9 7 7 15 18 8 21 16 30 22 7 Algoritmit 2 Kevät 2017 Luento 2 Ke 15.3.2017 14/29
Kekorakenne Tasolla i (paitsi viimeisellä) 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 viimeisen tason h lehtisolmuissa ja niiden jälkeen tason h 1 lehtisolmuissa Algoritmit 2 Kevät 2017 Luento 2 Ke 15.3.2017 15/29
Lisäys kekoon Säilytetään melkein täydellinen rakenne: Jos lehtisolmuja kahdella tasolla Uusi solmu tasolle h mahdollisimman vasemmalle Jos lehtisolmuja yhdellä tasolla Uusi solmu vasemmanpuoleisimman (rakenteellisessa järjestyksessä ensimmäisen) solmun vasemmaksi lapseksi Algoritmit 2 Kevät 2017 Luento 2 Ke 15.3.2017 16/29
Lisäys kekoon jatkuu Osittainen järjestys kuntoon: Jos lisätyn solmun arvo ei ole pienempi kuin tämän solmun vanhemman arvo, osittainen järjestys on kunnossa Muuten vaihdetaan lisätyn solmun ja sen vanhemman sisällöt keskenään Toistetaan lisätyn solmun ja sen vanhemman arvojen vertailua ja jatketaan, kunnes osittainen järjestys kunnossa Pahimmassa tapauksessa voidaan joutua toistamaan juurisolmuun saakka Algoritmit 2 Kevät 2017 Luento 2 Ke 15.3.2017 17/29
Poisto keosta Poistettava solmu on juurisolmu Säilytetään melkein täydellinen rakenne: Poistetaan viimeisen tason h oikeanpuoleisin solmu Sijoitetaan se juurisolmun tilalle Algoritmit 2 Kevät 2017 Luento 2 Ke 15.3.2017 18/29
Poisto keosta jatkuu Osittainen järjestys kuntoon: Jos uuden juurisolmun arvo ei ole suurempi kuin tämän solmun lapsien arvot, osittainen järjestys on kunnossa Muuten vaihdetaan solmun ja sen pienemmän lapsen sisällöt keskenään Toistetaan solmun ja sen lapsien arvojen vertailua ja jatketaan, kunnes osittainen järjestys kunnossa Pahimmassa tapauksessa voidaan joutua toistamaan lehtisolmutasolle saakka Algoritmit 2 Kevät 2017 Luento 2 Ke 15.3.2017 19/29
Keko-operaatioiden vaativuus Pahimmassa tapauksessa käydään läpi polku juuresta lehtisolmujen tasolle (jompaan kumpaan suuntaan) Keko melkein täydellinen, joten korkeus kertaluokkaa log n Operaatioiden aikavaativuus Θ(log n) Algoritmit 2 Kevät 2017 Luento 2 Ke 15.3.2017 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 2017 Luento 2 Ke 15.3.2017 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 2017 Luento 2 Ke 15.3.2017 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 Algoritmit 2 Kevät 2017 Luento 2 Ke 15.3.2017 23/29
Keko-operaatiot taulukolla lisaakekoon(int[] a, int alkio) { if (a[0] >= MAXPQ) {... } // Taulukko täynnä, // kasvata kokoa tai heitä poikkeus a[0]++; int i = a[0]; // Siirretään alkiota kohti juurta while ((i > 1) && (a[i/2] > alkio)) { a[i] = a[i/2]; i = i/2; } a[i] = alkio; } Algoritmit 2 Kevät 2017 Luento 2 Ke 15.3.2017 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 2017 Luento 2 Ke 15.3.2017 25/29
Keko-operaatiot taulukolla int poistapienin(int[] a) { if (a[0] == 0) {... } // Ei poistettavaa alkiota, // lopeta tai heitä poikkeus int alkio = a[1]; a[1] = a[a[0]]; a[0]--; korjaakeko(a, 1); return alkio; } Algoritmit 2 Kevät 2017 Luento 2 Ke 15.3.2017 26/29
Keon muodostaminen Rakennetaan keko alkioiden syöttövaiheessa: Kutsutaan lisaakekoon-algoritmia n kertaa Yhden lisäyksen aikavaativuus Θ(log n) Keon muodostaminen tällä tavalla Θ(n log n) Algoritmit 2 Kevät 2017 Luento 2 Ke 15.3.2017 27/29
Keon muodostaminen Rakennetaan keko, kun kaikki alkiot syötetty: Tallennetaan alkiot taulukkoon vapaassa 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 2017 Luento 2 Ke 15.3.2017 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 2017 Luento 2 Ke 15.3.2017 29/29