Algoritmit 1 Demot 2 7.-8.2.2018 Timo Männikkö
Tehtävä 1 (a) Ei-rekursiivinen algoritmi: etsipienin(t, n) { pnn = t[0]; for (i = 1; i < n; i++) { pnn = min(pnn, t[i]); return pnn; Silmukka suoritetaan n 1 kertaa O(n) Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 2/32
Tehtävä 1 (a) jatkuu Rekursiivinen algoritmi: etsipienin(t, n) { if (n == 1) return t[0]; else return min(etsipienin(t, n-1), t[n-1]); Suoritusaika muotoa { b, kun n = 1, T (n) = T (n 1) + c, kun n > 1, missä b, c > 0 vakioita Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 3/32
Tehtävä 1 (a) jatkuu Suoritusaika muotoa { b, kun n = 1, T (n) = T (n 1) + c, kun n > 1, missä b, c > 0 vakioita T (n) = T (n 1) + c = T (n 2) + 2c = T (n 3) + 3c = = T (1) + (n 1)c = b c + cn = O(n) Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 4/32
Tehtävä 1 (b) Ei-rekursiivinen algoritmi: asetaluku(t, n, luku) { for (i = 0; i < n; i++) { t[i] = luku; return; Silmukka suoritetaan n kertaa O(n) Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 5/32
Tehtävä 1 (b) jatkuu Rekursiivinen algoritmi: asetaluku(t, n, luku) { if (n == 0) return; else { t[n-1] = luku; asetaluku(t, n-1, luku); return; Suoritusaika muuten samaa muotoa kuin (a)-kohdassa paitsi että rekursio päättyy vasta kun n = 0 Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 6/32
Tehtävä 1 (b) jatkuu Suoritusaika muotoa { b, kun n = 0, T (n) = T (n 1) + c, kun n > 0, missä b, c > 0 vakioita T (n) = T (n 1) + c = T (n 2) + 2c = = T (0) + nc = b + cn = O(n) Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 7/32
Tehtävä 1 (c) Ei-rekursiivinen algoritmi: laskenollat(t, n) { lkm = 0; for (i = 0; i < n; i++) { if (t[i] == 0) lkm++; return lkm; Silmukka suoritetaan n kertaa O(n) Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 8/32
Tehtävä 1 (c) jatkuu Rekursiivinen algoritmi: laskenollat(t, n) { if (n == 0) return 0; else { if (t[n-1] == 0) return (laskenollat(t, n-1) + 1); else return (laskenollat(t, n-1)); Suoritusaika samaa muotoa kuin (b)-kohdassa O(n) Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 9/32
Tehtävä 2 (a) Tavalliset pino-operaatiot: push, pop, isempty, size, top operate: Poistaa pinon kaksi päällimmäistä alkiota ja korvaa ne yhdellä uudella alkiolla, joka on poistettujen alkioiden yhdiste operate(yhdiste,pino) { if (size(pino) < 2) return error; a = pop(pino); b = pop(pino); c = yhdiste(a,b); push(c,pino); Aputilaa tarvitaan vakiomäärä (muuttujat a, b ja c) Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 10/32
Tehtävä 2 (b) sink: Siirtää pinon päällimmäisen alkion alimmaiseksi, jolloin kaikki muut alkiot nousevat pinossa yhdellä askeleella ylöspäin Päällimmäinen alkio talteen, muut alkiot apupinoon Tallessa oleva alkio alkuperäisen pinon pohjalle Lopuksi alkiot apupinosta alkuperäiseen pinoon Aputilaa tarvitaan apupinolle (ja muille muuttujille) Aputilan koko samaa kertaluokkaa kuin alkuperäisen pinon koko Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 11/32
Tehtävä 2 (b) jatkuu sink(pino) { if (size(pino) < 1) return error; a = pop(pino); while (!isempty(pino)) { b = pop(pino); push(b,apu); // apupinoon push(a,pino); while (!isempty(apu)) { b = pop(apu); push(b,pino); // takaisin Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 12/32
Tehtävä 2 (c) flip: Kääntää pinon nurin, toisin sanoen vanha päällimäinen alkio siirtyy alimmaiseksi, toiseksi päällimmäinen alkio toiseksi alimmaiseksi jne. Siirretään alkiot taulukkoon (tai apupinoon) Siirretään alkiot takaisin uudessa järjestyksessä Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 13/32
Tehtävä 2 (c) jatkuu flip(pino) { n = size(pino); for (i = 1; i <= n; i++) a[i] = pop(pino); for (i = 1; i <= n; i++) push(a[i],pino); Aputilaa tarvitaan taulukolle (ja muille muuttujille) Aputilan koko samaa kertaluokkaa kuin alkuperäisen pinon koko Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 14/32
Tehtävä 3 (a) Merkkijono DAGEBFICH Lisätään merkki s pinoon p operaatiolla push(s,p) Poistetaan merkki pinosta operaatiolla pop(p) Pinoon ei saa lisätä merkkiä sellaisen merkin päälle, joka on aakkosissa aikaisemmin (koska silloin alle jäänyttä merkkiä ei voi poistaa oikealla hetkellä) Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 15/32
Tehtävä 3 (a) jatkuu Merkkijono DAGEBFICH push(d,1) push(a,1) pop(1) A push(g,2) push(e,2) push(b,1) pop(1) B push(f,3) push(i,4) Tarvitaan vähintään neljä pinoa push(c,1) pop(1) C pop(1) D pop(2) E pop(3) F pop(2) G push(h,1) pop(1) H pop(4) I Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 16/32
Tehtävä 3 (b) Merkkijono IDCBHGAFE push(i,1) push(d,1) push(c,1) push(b,1) push(h,2) push(g,2) push(a,1) pop(1) A pop(1) B Tarvitaan vähintään kaksi pinoa pop(1) C pop(1) D push(f,1) push(e,1) pop(1) E pop(1) F pop(2) G pop(2) H pop(1) I Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 17/32
Tehtävä 3 (c) Merkkijono DAGEBFICH Lisätään merkki s jonoon q operaatiolla enq(s,q) Poistetaan merkki jonosta operaatiolla deq(q) Jonoon ei saa lisätä merkkiä sellaisen merkin perään, joka on aakkosissa myöhemmin (koska silloin taakse jäänyttä merkkiä ei voi poistaa oikealla hetkellä) Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 18/32
Tehtävä 3 (c) jatkuu Merkkijono DAGEBFICH enq(d,1) enq(a,2) deq(2) A enq(g,1) enq(e,2) enq(b,3) deq(3) B enq(f,2) enq(i,1) Tarvitaan vähintään kolme jonoa enq(c,3) deq(3) C deq(1) D deq(2) E deq(2) F deq(1) G enq(h,2) deq(2) H deq(1) I Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 19/32
Tehtävä 3 (d) Merkkijono IDCBHGAFE enq(i,1) enq(d,2) enq(c,3) enq(b,4) enq(h,2) enq(g,3) enq(a,5) deq(5) A deq(4) B Tarvitaan vähintään viisi jonoa deq(3) C deq(2) D enq(f,4) enq(e,5) deq(5) E deq(4) F deq(3) G deq(2) H deq(1) I Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 20/32
Tehtävä 4 (a) first Lisätään listaan osoitin last, joka osoittaa viimeiseen alkioon Ensin erikoistapaus: if (first == null) // tyhjä lista last = null; Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 21/32
Tehtävä 4 (a) jatkuu last first last = first; while (last.next!= null) last = last.next; Täytyy etsiä listan viimeinen alkio Joudutaan käymään läpi koko lista Suoritusaika O(n) Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 22/32
Tehtävä 4 (b) first Vaihdetaan listan ensimmäinen ja viimeinen alkio keskenään Operaatio mielekäs vain jos listassa vähintään kaksi alkiota Ensin tarkistukset: if (first == null) return; // tyhjä lista if (first.next == null) return; // vain yksi alkio Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 23/32
Tehtävä 4 (b) jatkuu q p first p = osoitin viimeiseen alkioon q = osoitin toiseksi viimeiseen alkioon q = null; p = first; while (p.next!= null) { q = p; p = p.next; Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 24/32
Tehtävä 4 (b) jatkuu q p first p.next = first.next; q.next = first; first.next = null; first = p; Täytyy etsiä listan viimeinen ja toiseksi viimeinen alkio Suoritusaika O(n) Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 25/32
Tehtävä 4 (b) jatkuu q p first Mutta: Toimiiko, jos vain kaksi alkiota? Ei, sillä p.next = first.next; asettaa viimeisen alkion osoittamaan itseensä! Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 26/32
Tehtävä 4 (b) jatkuu q p first Jos vain kaksi alkiota: p.next = first; first.next = null; first = p; Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 27/32
Tehtävä 4 (b) jatkuu if (first == null) // tyhjä lista return; else if (first.next == null) // vain yksi alkio return; else { q = null; p = first; while (p.next!= null) { q = p; p = p.next; // nyt p osoittaa viimeiseen, q toiseksi viimeiseen if (q == first) // vain kaksi alkiota p.next = first; else { p.next = first.next; q.next = first; first.next = null; first = p; Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 28/32
Tehtävä 5 first last (a) Poistetaan listan ensimmäinen alkio (b) Lisätään listan loppuun yksi alkio (c) Tehdään listasta rengaslista Kaikissa tapauksissa tarvittaviin alkioihin päästään käsiksi suoraan (ilman listan läpikäyntiä) Suoritusajat O(1) Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 29/32
Tehtävä 5 (a) first last if (first == null) // tyhjä lista return; else if (first.next == null) { // vain yksi alkio first = null; last = null; else { first = first.next; first.prev = null; Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 30/32
Tehtävä 5 (b) first p last // p osoitin lisättävään alkioon p.next = null; p.prev = last; if (first == null) // lisäys tyhjään listaan first = p; else last.next = p; last = p; Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 31/32
Tehtävä 5 (c) first last if (first!= null) { // vain ei-tyhjälle listalle first.prev = last; last.next = first; Algoritmit 1 Kevät 2018 Demot 2 7.-8.2.2018 32/32