Algoritmit 2 Luento 3 Ti 20.3.2018 Timo Männikkö
Luento 3 Järjestäminen eli lajittelu Kekorakenne Kekolajittelu Hajautus Yhteentörmäysten käsittely Ketjutus Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 2/29
Järjestäminen eli lajittelu Lajittelu: Taulukon, listan, tiedoston jne. järjestäminen suuruusjärjestykseen jonkin avainkentän (tai avainkenttien) mukaan Lajittelun stabiilisuus: Alkiot, joilla sama avainkentän arvo, säilyttävät alkuperäisen keskinäisen järjestyksensä Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 3/29
Lajittelumenetelmiä Raakaan voimaan perustuvia: Kuplalajittelu Lisäyslajittelu Valintalajittelu Osittamiseen perustuvia: Lomituslajittelu Pikalajittelu Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 4/29
Prioriteettijono Kokoelma alkioita, joihin liittyy jokin prioriteetti Lisää alkio -operaatio Poista pienin -operaatio Prioriteettijonon stabiilisuus: Mikä alkio poistetaan yhtäsuurien prioriteettien tapauksessa Poista pienin Minimiprioriteettijono Poista suurin Maksimiprioriteettijono Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 5/29
Kekorakenne 5 9 7 7 15 18 8 21 16 30 22 7 Osittain järjestetty: Solmun prioriteetti ei ole suurempi kuin sen lapsisolmujen prioriteetit Melkein täydellinen: Ylemmät tasot täynnä, alimmalla tasolla solmut vasemmalla Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 6/29
Keon muodostaminen teekeko(int[] a) // Oletus: a[0]:ssa on alkioiden lukumäärä // Muodostaa keon taulukkoon // tallennetuista n:stä alkiosta korjaakeko(int[] a, int i) // Oletus: a[i]:n alipuissa on kekorakenteet // Siirtää alkiota a[i] kohti lehtisolmuja // kunnes osittainen järjestys // paikasta i alkaen on kunnossa Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 7/29
Alkioiden järjestäminen Alkioiden lajittelu prioriteettijonon avulla: for (i = 1; i <= n; i++) lisää alkio prioriteettijonoon; for (i = 1; i <= n; i++) poista pienin prioriteettijonosta; Alkiot poistetaan kasvavassa järjestyksessä Jos lisäys ja poisto toteutettu ajassa Θ(log n) Lajittelun aikavaativuus Θ(n log n) Mutta: Vaatii aputilaa n paikkaa (prioriteettijono alkuperäisen taulukon lisäksi) Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 8/29
Kekolajittelu (heapsort) Jos käytetään edellä esitettyä kekototeutusta: Voidaan lajittelu tehdä alkuperäisessä taulukossa, ilman aputaulukoita Vaihdetaan keon ensimmäinen ja viimeinen alkio Jätetään viimeinen alkio keon ulkopuolelle Korjataan yhtä alkiota pienemmän keon osittainen järjestys kuntoon Jatketaan kunnes keossa enää yksi alkio Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 9/29
Kekolajittelu kekolajittelu(int[] a, int n) { a[0] = n; teekeko(a); for (int i = n; i > 1; i--) { swap(a[1], a[i]); a[0]--; korjaakeko(a, 1); } } teekeko Θ(n) ja korjaakeko Θ(log n) Aikavaativuus Θ(n log n) Aputilaa vain vakiomäärä Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 10/29
Kekolajittelu Huom: Jos keko on minimiprioriteettijono, alkiot saadaan vähenevässä järjestyksessä Jos halutaan kasvavassa järjestyksessä, voidaan käyttää maksimiprioriteettijonoa: Jokaisen solmun prioriteetti ei ole pienempi kuin sen lapsisolmujen prioriteetit Algoritmeja lisaakekoon ja korjaakeko muutetaan vastaavasti Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 11/29
Hakemisto Hakemisto (sanakirja, dictionary): Tallennusrakenne, jossa pääoperaatio on alkion hakeminen Tallennettuna avain-alkio-pareja Haku halutaan mahdollisimman nopeaksi Voidaan käyttää tuttuja rakenteita: Lineaarinen lista (järjestetty, järjestämätön) Tasapainoinen binääripuu Satunnaistamiseen perustuu: Hajautus (hashing) Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 12/29
Hakemisto taulukossa Taulukko tallennusrakenteena: Nopea alkion haku, kun tunnetaan sen indeksi (paikka taulukossa) Haun, lisäyksen ja poiston aikavaativuus Θ(1) (jos alkioita ei tarvitse siirrellä) Taulukko sopii hyvin hakemistoksi, kun indeksointi tehdään järkevästi Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 13/29
Hakemisto taulukossa Käytetään taulukon indekseinä avaimien arvoja Mutta: Mahdollisten avaimien arvoalue voi olla suuri Esim: Avain 32-bittinen kokonaisluku Taulukon koko 2 32 4 miljardia Lisäksi: Usein hakemistossa esiintyy vain pieni osa mahdollisista avaimista Suuri osa taulukosta tyhjänä Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 14/29
Hajautus Hajautuksen idea: Taulukon koko samaa kertaluokkaa kuin tallennettavien alkioiden lukumäärä Alkion indeksi lasketaan avaimen arvosta hajautusfunktion avulla Pyritään siihen, että haun keskimääräinen aikavaativuus olisi Θ(1) Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 15/29
Hajautus Tallennettavia alkioita n Taulukon koko m Hajautusfunktio h : {mahdolliset avaimet} {0, 1,..., m 1} Avainta k vastaavan alkion indeksi on h(k) (avaimen k kotiosoite) Mahdollisia avaimia paljon enemmän kuin m Usealla avaimella on sama kotisoite Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 16/29
Hajautus Yhteentörmäys: Jos k 1 k 2, mutta h(k 1 ) = h(k 2 ) Sanotaan, että k 1 ja k 2 ovat synonyymejä Synonyymeja vastaavia alkioita ei voida tallentaa kaikkia samaan muistipaikkaan Yhteentörmäykset täytyy käsitellä jotenkin Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 17/29
Hajautusfunktio Hyvä hajautusfunktio: Mahdollisimman vähän yhteentörmäyksiä Jos tallennettavien alkioiden avaimia ei tunneta etukäteen, yhteentörmäyksiä ei voi välttää Hajauttaa alkiot tasaisesti taulukkoon Vaikea toteuttaa, jos tallennettavien alkioiden avaimien jakaumaa ei tunneta etukäteen Helppo laskea Helppo ohjelmoida, nopea laskea (mielellään vakioaikainen Θ(1)) Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 18/29
Numeroiden hajautus Suora hajautus: Avaimet kokonaislukuja väliltä [a, b] Hajautustaulukon koko m = b a + 1 Hajautusfunktio h(x) = x a Käyttökelpoinen, jos välillä [a, b] ei suuria aukkoja Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 19/29
Numeroiden hajautus Jakolaskumenetelmä: Hajautusfunktio h(x) = x mod m (jakolaskun x/m jakojäännös) Joitakin m:n arvoja kannattaa välttää (esim. 2:n potenssit) Suositellaan, että m olisi alkuluku, ei lähellä jotain 2:n potenssia Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 20/29
Numeroiden hajautus Bittimenetelmä: Hajautustaulukon koko m = 2 k Hajautusfunktio h(x) = k bittiä jostain sopivasta kohtaa x:ää Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 21/29
Numeroiden hajautus Kertolaskumenetelmä: Hajautustaulukon koko m = 2 k Valitaan vakio a, 0 < a < 1 Esimerkiksi a = ( 5 1)/2 0,61803 Hajautusfunktio h(x) = mxa mod m Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 22/29
Merkkijonojen hajautus Merkkijono muunnetaan kokonaisluvuksi z Esimerkiksi: z = n 1 i=0 Bn i 1 c i mod 2 r, missä c 0, c 1,..., c n 1 ovat merkkijonon merkkien lukuarvot (esim. ASCII-koodi) B jokin sopiva vakio (esim. B = 131) r tietokoneen sanan pituus (32 tai 64) Voidaan valita myös vain tietty osa merkkijonon merkeistä Kokonaisluku z hajautetaan esimerkiksi jakojäännösmenetelmällä Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 23/29
Yhteentörmäysten käsittely Hajautustaulukko t, koko m Alkion, jonka avain k, kotiosoite on h(k) Jos kahdella tai useammalla avaimella sama kotiosoite Yhteentörmäys Menetelmiä: Ketjutus Avoin osoitteenmuodostus Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 24/29
Ketjutus Jokaiselle kotiosoitteelle lineaarinen lista Listat tallennetaan dynaamiseen muistiin Hajautustaulukossa osoittimet listojen ensimmäisiin alkioihin (tai null, jos alkioita ei ole) Algoritmit yksinkertaisia lista-algoritmeja Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 25/29
Ketjutus Alkion haku: 1. Hajautetaan haettavan alkion avain k indeksiksi h(k) väliltä [0, m 1] 2. Taulukosta t osoitin r = t[h(k)] Jos r = null, alkiota ei ole Muuten käydään listaa läpi, kunnes avainta k vastaava alkio löytyy Jos tullaan listan loppuun, alkiota ei ole Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 26/29
Ketjutus Alkion lisäys: 1. Hajautetaan lisättävän alkion avain k indeksiksi h(k) väliltä [0, m 1] 2. Taulukosta t osoitin r = t[h(k)] Lisätään alkio ensimmäiseksi alkioksi listaan, johon r osoittaa Jos halutaan alkioiden yksikäsitteisyys: Käydään lista läpi ja tarkistetaan, onko avainta k vastaava alkio jo tallennettuna Lisätään vain jos listasta ei löydy samaa alkiota Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 27/29
Ketjutus Alkion poisto: 1. Hajautetaan poistettavan alkion avain k indeksiksi h(k) väliltä [0, m 1] 2. Taulukosta t osoitin r = t[h(k)] Jos r = null, alkiota ei ole Muuten käydään listaa läpi, kunnes avainta k vastaava alkio löytyy Poistetaan alkio listasta Jos tullaan listan loppuun, alkiota ei ole Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 28/29
Ketjutus Aikavaativuus: Oletetaan: Hajautus mahdollisimman tasaisesti Yhteen kotiosoitteeseen hajautuu keskimäärin n/m avainta Haku ja poisto Θ(n/m) Lisäys Θ(n/m), jos yksikäsitteisyys tarkistetaan (Θ(1), jos yksikäsitteisyyttä ei tarkisteta) Jos m > n/2, ketjutus toimii yleensä hyvin Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018 29/29