58131 Tietorakenteet ja algoritmit (kevät 2013) Kurssikoe 1, , vastauksia

Samankaltaiset tiedostot
(a) L on listan tunnussolmu, joten se ei voi olla null. Algoritmi lisäämiselle loppuun:

Koe ma 1.3 klo salissa A111, koeaika kuten tavallista 2h 30min

58131 Tietorakenteet ja algoritmit (kevät 2016) Ensimmäinen välikoe, malliratkaisut

Hakupuut. tässä luvussa tarkastelemme puita tiedon tallennusrakenteina

811312A Tietorakenteet ja algoritmit II Perustietorakenteet

Algoritmit 2. Luento 4 To Timo Männikkö

TKT20001 Tietorakenteet ja algoritmit Erilliskoe , malliratkaisut (Jyrki Kivinen)

Algoritmit 2. Luento 7 Ti Timo Männikkö

811312A Tietorakenteet ja algoritmit, , Harjoitus 5, Ratkaisu

58131 Tietorakenteet ja algoritmit (kevät 2014) Uusinta- ja erilliskoe, , vastauksia

58131 Tietorakenteet (kevät 2008) 1. kurssikoe, ratkaisuja

Algoritmit 2. Luento 4 Ke Timo Männikkö

58131 Tietorakenteet ja algoritmit Uusinta- ja erilliskoe ratkaisuja (Jyrki Kivinen)

Tarkennamme geneeristä painamiskorotusalgoritmia

AVL-puut. eräs tapa tasapainottaa binäärihakupuu siten, että korkeus on O(log n) kun puussa on n avainta

Tietorakenteet, laskuharjoitus 3, ratkaisuja

3. Hakupuut. B-puu on hakupuun laji, joka sopii mm. tietokantasovelluksiin, joissa rakenne on talletettu kiintolevylle eikä keskusmuistiin.

Algoritmit 2. Luento 2 Ke Timo Männikkö

Tietorakenteet, laskuharjoitus 7, ratkaisuja

(p j b (i, j) + p i b (j, i)) (p j b (i, j) + p i (1 b (i, j)) p i. tähän. Palaamme sanakirjaongelmaan vielä tasoitetun analyysin yhteydessä.

811312A Tietorakenteet ja algoritmit V Hash-taulukot ja binääriset etsintäpuut

Koe ma 28.2 klo salissa A111, koeaika kuten tavallista 2h 30min

Algoritmit 1. Demot Timo Männikkö

Algoritmit 2. Luento 2 To Timo Männikkö

ALGORITMIT 1 DEMOVASTAUKSET KEVÄT 2012

58131 Tietorakenteet Erilliskoe , ratkaisuja (Jyrki Kivinen)

811312A Tietorakenteet ja algoritmit, , Harjoitus 5, Ratkaisu

Algoritmit 1. Luento 4 Ke Timo Männikkö

Algoritmit 2. Luento 3 Ti Timo Männikkö

Miten käydä läpi puun alkiot (traversal)?

Ohjelmoinnin perusteet Y Python

811312A Tietorakenteet ja algoritmit Kertausta jälkiosasta

Algoritmit 2. Luento 3 Ti Timo Männikkö

Algoritmit 1. Luento 7 Ti Timo Männikkö

811312A Tietorakenteet ja algoritmit Kertausta kurssin alkuosasta

2. Seuraavassa kuvassa on verkon solmujen topologinen järjestys: x t v q z u s y w r. Kuva 1: Tehtävän 2 solmut järjestettynä topologisesti.

Algoritmit 1. Luento 3 Ti Timo Männikkö

Algoritmit 1. Luento 8 Ke Timo Männikkö

v 1 v 2 v 3 v 4 d lapsisolmua d 1 avainta lapsen v i alipuun avaimet k i 1 ja k i k 0 =, k d = Sisäsolmuissa vähint. yksi avain vähint.

Algoritmit 2. Luento 5 Ti Timo Männikkö

Ohjelmoinnin peruskurssi Y1

4. Perustietorakenteet: pino, jono ja lista

58131 Tietorakenteet ja algoritmit (syksy 2015) Toinen välikoe, malliratkaisut

Tehtävän V.1 ratkaisuehdotus Tietorakenteet, syksy 2003

4. Joukkojen käsittely

Algoritmit 1. Luento 6 Ke Timo Männikkö

1. (a) Seuraava algoritmi tutkii, onko jokin luku taulukossa monta kertaa:

Pinot, jonot, yleisemmin sekvenssit: kokoelma peräkkäisiä alkioita (lineaarinen järjestys) Yleisempi tilanne: alkioiden hierarkia

1 Puu, Keko ja Prioriteettijono

1.1 Tavallinen binäärihakupuu

Algoritmit 1. Luento 12 Ke Timo Männikkö

811312A Tietorakenteet ja algoritmit, , Harjoitus 7, ratkaisu

Algoritmit 1. Luento 5 Ti Timo Männikkö

Algoritmit 1. Luento 12 Ti Timo Männikkö

811120P Diskreetit rakenteet

1.1 Pino (stack) Koodiluonnos. Graafinen esitys ...

A TIETORAKENTEET JA ALGORITMIT KORVAAVAT HARJOITUSTEHTÄVÄT 3, DEADLINE KLO 12:00

Algoritmit 2. Luento 6 Ke Timo Männikkö

Tietorakenteet, laskuharjoitus 6,

Algoritmit 2. Luento 6 To Timo Männikkö

Binäärihaun vertailujärjestys

Tietorakenteet, laskuharjoitus 10, ratkaisuja. 1. (a) Seuraava algoritmi tutkii, onko jokin luku taulukossa monta kertaa:

811120P Diskreetit rakenteet

Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari Korhonen

6. Hakupuut. Hakupuu (engl. search tree) on listaa huomattavasti edistyneempi tapa toteuttaa abstrakti tietotyyppi joukko

4 Tehokkuus ja algoritmien suunnittelu

A TIETORAKENTEET JA ALGORITMIT

Kaksiloppuinen jono D on abstrakti tietotyyppi, jolla on ainakin seuraavat 4 perusmetodia... PushFront(x): lisää tietoalkion x jonon eteen

Algoritmit 2. Demot Timo Männikkö

Algoritmit 1. Demot Timo Männikkö

2. Perustietorakenteet

58131 Tietorakenteet ja algoritmit (kevät 2013) Kurssikoe 2, , vastauksia

Oikeasta tosi-epätosi -väittämästä saa pisteen, ja hyvästä perustelusta toisen.

58131 Tietorakenteet ja algoritmit Uusinta- ja erilliskoe malliratkaisut ja arvosteluperusteet

ITKP102 Ohjelmointi 1 (6 op)

Algoritmit 2. Luento 8 To Timo Männikkö

ITKP102 Ohjelmointi 1 (6 op)

Algoritmit 2. Luento 5 Ti Timo Männikkö

Ohjelmoinnin perusteet Y Python

Datatähti 2019 loppu

Algoritmit 1. Luento 9 Ti Timo Männikkö

f(n) = Ω(g(n)) jos ja vain jos g(n) = O(f(n))

Ohjelmoinnin perusteet Y Python

Algoritmit 2. Luento 14 Ke Timo Männikkö

Tietorakenteet ja algoritmit - syksy

Algoritmi on periaatteellisella tasolla seuraava:

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin perusteet Y Python

A TIETORAKENTEET JA ALGORITMIT

Tietorakenteet, laskuharjoitus 2,

5. Keko. Tietorakenne keko eli kasa (heap) on tehokas toteutus abstraktille tietotyypille prioriteettijono, jonka operaatiot ovat seuraavat:

lähtokohta: kahden O(h) korkuisen keon yhdistäminen uudella juurella vie O(h) operaatiota vrt. RemoveMinElem() keossa

58131 Tietorakenteet (kevät 2009) Harjoitus 6, ratkaisuja (Antti Laaksonen)

Ohjelmoinnin perusteet Y Python

8. Yhteenvetoa. abstrakti tietotyyppi: mitä datalle halutaan tehdä tietorakenne: miten se tehdään (talletusrakenne, operaatioden toteutus)

5. Hajautus. Tarkastellaan edelleen sivulla 161 esitellyn joukkotietotyypin toteuttamista

private TreeMap<String, Opiskelija> nimella; private TreeMap<String, Opiskelija> numerolla;

Määrittelydokumentti

Algoritmit 1. Luento 10 Ke Timo Männikkö

Aikavaativuuden perussäännöt

Transkriptio:

58131 Tietorakenteet ja algoritmit (kevät 2013) Kurssikoe 1, 25.2.2013, vastauksia 1. (a) O-merkintä Ω-merkintä: Kyseessä on (aika- ja tila-) vaativuuksien kertalukumerkinnästä. O-merkintää käytetään ylärajan esittämiseen. Se siis kertoo, että algoritmi ei toimi koskaan huonommin kuin mitä merkintä on. Ω-merkintää käytetään taas kuvaamaan vaativuuden alarajaa. (b) binääripuu binäärihakupuu: Molemmat ovat puita. Binääripuu on puu, jonka jokaisella solmulla on korkeintaan kaksi lasta. Binääripuussa solmujen järjestyksellä ei ole väliä. Binäärihakupuu, on binääripuu, jonka solmut toteuttavat binäärihakupuuehdon: jos solmu v on solmun x vasemmassa alipuussa, niin v.key < x.key jos solmu o on solmun x oikeassa alipuussa, niin x.key < o.key (c) ketjutus avoin hajautus: Kyseessä on tapa hoitaa hajautuksen yhteentörmäyksiä. Ketjutuksessa yhteentörmäävät avaimet tallennetaan linkitettyihin listoihin. Avoimessa hajautuksessa kukin avain talletetaan suoraan hajautustauluun. Mikäli paikka on jo varattu, etsitään avaimelle toinen indeksi hajautustaulusta. Jos uusikin paikka on varattu, jatketaan etsimistä, kunnes vapaa paikka löytyy. Avoimessa hajautuksessa hajautustauluun mahtuu maksimissaan hajautustaulun koon verran avaimia, kun taas ketjutuksessa linkitettyjen listojen vuoksi ei vastaavaa kokorajaa ole. (d) primäärinen kasautuminen sekundäärinen kasautuminen: Kyseessä on hajautuksen useiden yhteentörmäysten ongelmatyyppejä. Primäärinen kasaantuminen voi esiintyä, kun avoimessa hajautuksessa on käytössä lineaarinen kokeilujono, jossa kokeillaan aina seuraavaa taulukon paikkaa, kunnes löydetään vapaa. Tällöin voi helposti muodostua pitkiä varattuja alueita. Sekundäärinen kasautuminen taas viittaa tilanteeseen, missä avoimessa hajautuksessa eri avaimilla on samat kokeilujonot, jolloin samaan hajautusarvoon kuvautuvat avaimet tarvitsevat helposti monta kokeilua ennen kuin löytyy vapaa paikka taulukosta. Tämä esiintyy esim. neliöisessä kokeilussa. 2. Tehtävään oli oleellisesti kaksi erilaista ratkaisutapaa: 1. Käydään puu läpi taso kerrallaan jonoa apuna käyttäen, aivan kuten viidensien laskuharjoitusten tehtävässä 4b. Tulostuksen sijasta laitammekin alkiot pinoon ja tyhjennämme pinon vasta kun koko puu on pinossa. Pseudokoodina:

tasotalhaaltaylos1(root) if root == Nil return Otetaan käyttöön apujono Q ja pino P enqueue(q,root) while not isempty(q) x = dequeue(q) push(p,x) if x.left!= Nil enqueue(q,x.left) if x.right!= Nil enqueue(q,x.right) while not isempty(p) print(pop(p)) Merkitään puun solmujen lukumäärää kirjaimella n. Algoritmin aikavaativuus on O(n), sillä siinä on kaksi peräkkäistä silmukkaa, jotka molemmat käyvät puun alkiot kertaalleen läpi. Algoritmin tilavaativuus on myös O(n), sillä pinossa P on ensimmäisen silmukan jälkeen talletettuna kaikki puun alkiot. 2. Toisesta tavasta on useita erilaisia versioita ja ne perustuvat puun korkeuteen. Ensin lasketaan puun korkeus käyttäen hyväksi esimerkiksi luentomateriaalin sivun 172 algoritmia laske-korkeus (tämäkin algoritmi kuuluu kirjoittaa auki). Merkitään puun korkeutta kirjaimella h. Tämän jälkeen puu käydään läpi h kertaa, tulostaen aina vain yhden tason solmut. Pseudokoodina: tasotalhaaltaylos2(root) if root == Nil return h = laskekorkeus(root) while h > 0 tulostasolmuttasolta(h,root) h--

tulostasolmuttasolta(i,x) if x == Nil return if i == 0 print(x) else tulostasolmuttasolta(i-1,x.left) tulostasolmuttasolta(i-1,x.right) Merkitään edelleen puun solmujen lukumäärää kirjaimella n ja korkeutta kirjaimella h. Nyt algoritmin aikavaativuus on O(n h), sillä metodin laskekorkeus aikavaativuus on O(n), ja metodin tulostasolmuttasolta on O(n). Lisäksi metodia tulostasolmuttasolta kutsutaan silmukassa, joka suoritetaan h kertaa. Tilavaativuus on luokkaa O(n), sillä rekursiopinossa on pahimmillaan n instanssia. Tämä tapahtuu silloin, kun puu on esimerkiksi oikealle suuntautuva ketju. Yleisiä virheitä: Jälkijärjestyksen, sisäjärjestyksen tai esijärjestyksen käyttö. Kahden pinon käyttö. Tilavaativuus väärin ratkaisutavassa 1. Vääränlaiset läpikäynnit eivät toimi esimerkiksi seuraavanlaiseen puuhun. 1 2 3 \ 4 5 6 \ 7 3. Annettu AVL-puu oli seuraava: 8 18 \ 6 13 20 12 (a) Puun saattavat epätasapainoon alkioiden 9,19 tai 21 lisääminen.

(b) Lisätään ensin alkio 11 8 18 \ 6 13 20 12 11 Nyt solmu 13 on alin solmu, joka on epätasapainossa. Koska epätasapaino on solmun 13 vasemman lapsen vasemmassa alipuussa, niin teemme kierron oikealle: 8 18 \ 6 12 20 11 13 Nyt puu on taas tasapainossa, joten voimme lisätä alkion 10: 8 18 \ 6 12 20 11 13 10 Nyt 8 on alin solmu, joka on epätasapainossa. Koska epätasapainon aiheuttaja löytyy solmun 8 oikean lapsen vasemmasta elipuusta, niin teemme ensin solmulle 12 kierron oikealle ja sen jälkeen kierrämme solmua 8 vasemmalle:

8 18 11 18 \ \ 6 11 20 8 12 20 \ 10 12 6 10 13 \ 13 Nyt puu on jälleen tasapainossa (c) Huom: Nyt aloitamme alkuperäisestä puusta. 8 18 \ 6 13 20 12 Alkion 18 poistaminen saattaa solmun epätasapainoon. 8 20 6 13 12 Koska epätasapainon aiheuttaja on solmun vasemman lapsen oikeassa alipuussa, niin kierrämme ensin solmua 8 vasemmalle, ja tämän jälkeen solmua oikealle. 13 13 20 8 \ 8 6 12 20 6 12 Nyt puu on jälleen tasapainossa ja voimme poistaa alkion 8. Koska alkiolla 8 on kaksi lasta, niin sen paikalla tulee luvun 8 seuraaja, eli luku 12.

13 12 6 20 Yleisiä virheitä: Kiertoja tehtiin enemmän kuin pitäisi. Korjattiin jotain muuta alkiota kuin alinta, joka on epätasapainossa. 4. (a) Vastauksista piti tulla selväksi mitä pakan operaatioilta vaaditaan, ja jokin tai joitakin ratkaisuita niiden vakioaikaisuuteen saattamiseksi. Esimerkiksi: Listan alkua koskevissa insert ja remove operaatioissa tarvitsee käsitellä ainostaan listan ensimmäistä tietuetta, sekä sen naapureita. Tämä pätee myös listan loppua käsitteleville insert ja remove operaatioille. Tähän käsittelyyn liittyy ainostaan solmujen viitteiden päivitystä, joka tapahtuu vaikioaikaisilla sijoituslauseilla. Ratkaisuksi riittää siis sellainen kahteen suuntaan linkitetty lista, jolla päästään käsiksi sekä listan loppuun, että listan alkuun vakioajassa. Ratkaisuksi kelpaa siis esimerkiksi rengaslista, jossa listan ensimmäisen alkion prev viitteellä päästään listan viimeiseen alkioon. Tätä, ja toista mahdollista ratkaisua jossa listan lopusta pidetään kirjaa erillisellä P.tail kentällä, esitellään (b)-kohdan vastauksessa. (b) Pakka voidaan esittää muunmuassa kahteen suuntaan linkitettynä rengaslistana. Tällöin operaatiot ovat kurssin konventioita noudattaen seuraavanlaiset: insertfirst(p, x) 2 P.head = x 3 x.next = x 4 x.prev = x 5 return 6 x.prev = P.head.prev 7 P.head.prev.next = x 8 x.next = P.head 9 P.head.prev = x 10 P.head = x Algoritmi insertfirst koostuu kahdesta suoritushaarasta. Jos algoritmille annettu pakka on tyhjä, suoritetaan ehdon tarkistuksen jälkeen (rivi 1) suorittamaan rivit 2-5. Muussa tapauksessa suoritetaan rivit 6-10. Rivit 2-5 koostuvat vakioaikaisista sijoitusoperaatioista. Sama pätee riveihin 6-10. Rivin 1 ehtolause koostuu tasan yhdesta aliohjelmakutsusta: kutsutaan empty funktiota pakalle. Oletetaan että empty funktio on vakioaikainen aliohjelma, ja näytetään tämä vasta empty operaation yhteydessä. Nyt rivin 1 vaatima suoritusaika on jokin vakio c 1. Suoritusaika tulee

tällöin olemaan c 1 + max{ 5 i=2 c i, 10 i=6 c i} = O(1), missä c i on rivin i vaatima vakiosuoritusaika. Algoritmin insertfirst tilavaativuus on myös vakio. Algoritmissa käytetään ainoastaan annettuja muuttujia P ja x, eikä uusia muuttujia alusteta missään vaiheessa. Aliohjelmaa empty kutsutaan jokaisessa insertfirst suorituksessa tasan kerran, joten se muodostaa vain yhden aktivaatiotietueen, eikä siten aktivaatiotietuepinonkaan koko kasva. insertlast(p, x) 2 P.head = x 3 x.next = x 4 x.prev = x 5 return 6 x.prev = P.head.prev 7 P.head.prev.next = x.prev 8 x.next = P.head 9 P.head.prev = x Operaatio insertlast on hyvin samankaltainen insertfirst:n kanssa. Siinä suoritetaan ehtolausekkeen jälkeisessä haarassa yksi sijoitus vähemmän. Olettaen että empty voidaan suorittaa ajassa O(1), voidaan tämäkin algoritmi suorittaa ajassa O(1), sillä tämänkin algoritmin kumpikin haara koostuu vakioaikaisista sijoitusoperaatioista. Tilavaativuuskin on sama kuin algoritmissa insertfist, täsmälleen samoin perustein. removefirst(p, x) 2 return NIL 3 if P.head == P.head.next Jos ainoa alkio 4 retval = P.head 5 P.head = NIL 6 return retval 7 retval = P.head 8 P.head.prev.next = P.head.next 9 P.head = P.head.next 10 P.head.prev = retval.prev 11 return retval Algoritmin removefirst suoritus voi jakautua kolmeen eri haaraan. Olettaen, että funktio empty on vakioaikainen, suoritetaan rivi 1 vakioajassa. Mikäli empty palauttaa arvon true, suoritetaan ensimmäinen haara, joka koostuu pelkästään vakioaikaisesta return lauseesta. Muussa tapauksessa suoritetaan rivin 3 ehtolause, joka koostuu vain yhdestä vakioaikaisesta

loogisesta operaattorista käytettyjen tietueiden kentille. Rivin kolme ehtolause on siis myös vakioaikainen. Rivit 4-6 ovat myös vakioaikaiset, sillä ne koostuvat sijoitusoperaatioista, ja return lauseesta. Muussa tapauksessa suoritettavat rivit 7-11 koostuvat myös pelkästään sijoituslauseista ja return lauseesta. Operaatio removefirst on siten vakioaikainen. Operaatiossa removefirst käytetään yhtä apumuuttujaa, nimeltään retval, jota käytetään muissa haaroissa kuin ensimmäisessä. Tämä, sekä empty aliohjelman aktivaatiotietue vievät vakiomäärän muistia, joten remove- First suoriutuu vakiotilassa. removelast(p, x) 2 return NIL 3 if P.head == P.head.next Jos ainot alkio 4 retval = P.head 5 P.head = NIL 6 return retval 7 retval = P.head.prev 8 retval.prev.next = retval.next 9 P.head.prev = retval.prev 10 return retval Algoritmin removelast tila- ja aikavaativuus ovat samat kuin remove- First:llä, sillä vain viimeinen suoritushaara on erilainen, ja sekin on yhtä apumuuttujaa käyttävä, sekä sijoitus- ja return-lauseesta koostuva. empty(p) 1 return P.head == NIL Funktion empty suoritus on selvästi vakioaikainen, sillä se koostuu return lauseesta, joka palauttaa yhden loogisen operaattorin evaluoinnin tuloksen, jonka toinen operandi on annetun P-tietueen kenttä, ja toinen on globaalisti tunnettu NIL arvo. Se suoriutuu myös vakiotilassa, sillä se ei käytä yhtäkään aliohjelmakutsua, tai alusta yhtäkään muuttujaa. Koska empty voidaan suorittaa ajassa O(1), voidaan myös ylläkuvatut operaatiot suorittaa vakioajassa. Pakkaa voidaan esittää myös esim. niin että sillä on kaksi kenttää: P.head ja P.tail jotka viittaavat pakan alimpaan ja ylimpään alkioon. Ne ovat siis aluksi NIL, kuten ollaan totuttu näkemään pelkästään listan L.head tapauksessa. Nyt operaatiot ovat seuraavanlaisia:

insertfirst(p, x) 1 x.next = P.head 2 x.prev = NIL 3 if P.head!= NIL 4 P.head.prev = x 5 else 6 P.tail = x 7 P.head = x insertlast(p, x) 1 x.prev = P.tail 2 x.prev = NIL 3 if P.tail!= NIL 4 P.tail.prev = x 5 else 6 P.head = x 7 P.tail = x removefirst(p) 2 return NIL 3 retval = P.head 4 if P.head.next!= NIL 5 P.head = P.head.next 6 P.head.prev = NIL 7 else 8 P.head = NIL 9 P.tail = NIL 10 return retval removelast(p) 2 return NIL 3 retval = P.tail 4 if P.tail.prev!= NIL 5 P.tail = P.tail.prev 6 P.tail.next = NIL 7 else 8 P.head = NIL 9 P.tail = NIL 10 return retval empty(p) 1 return P.head == NIL Tässä esitystavassa aika- ja tilavaativuudet ovat samat kuin rengaslistatoteutuksella. Analyysi voidaan tehdä analogisesti, mutta on jätetty tässä suuren samankaltaisuuden vuoksi laatimatta.

Myös kaikki muut tavat esittää pakka kahteen suuntaan linkitettynä listana ovat hyväksyttäviä. On esimerkiksi hyväksyttävää käyttää kahteen suuntaan linkitettyä tunnussolmullista rengaslistaa, tai tavallista kahteen suuntaan linkitettyä listaa, jolloin operaatiot eivät enää olekaan vakioaikaisia. Arvostelusta: Aika- ja tilavaativuudesta sai yhden pisteen.