A274101 TIETORAKENTEET JA ALGORITMIT KORVAAVAT HARJOITUSTEHTÄVÄT 3, DEADLINE 9.2.2005 KLO 12:00 PISTETILANNE: www.kyamk.fi/~atesa/tirak/harjoituspisteet-2005.pdf Kynätehtävät palautetaan kirjallisesti luennoitsijalle ja ohjelmointitehtävät sähköisesti osoitteeseen: teemu.saarelainen@kyamk.fi Katso, että palautuksista löytyy ainakin seuraavat tiedot: 1. Nimi, opiskelijanumero, vuosikurssi, päiväys 2. Kurssi ja tehtävien numero (esim. H1 ja K.1. a), jne.) 3. Ohjelmointitehtävien osalta palautetaan zip-paketti, jossa i. Yksi sähköinen dokumentti (Word, PDF, LaTeX, tms.) sisältäen ohjelmakoodit sekä ohjelmien tulostuksen/ratkaisut, koodi pitää olla kommentoitua! ii. varsinainen ohjelmakoodi + kääntö- ja/tai ajokomennot suorittava skripti (.bat,.sh, tms.) ENSIMMÄISTEN TEHTÄVIEN OSALTA VAIN MURTO-OSA TEKI OHJEEN MUKAAN! SEURAAVILLA KERROILLA VIRHEISTÄ SAKOTETAAN TEHTÄVÄT OVAT HENKILÖKOHTAISIA VÄLTTÄKÄÄ SUORAA COPY-PASTEA HUOM!!! MIKÄLI TEHTÄVIEN SUORITUKSESSA TAI PALAUTUKSEEN LIITTYEN TULEE ONGELMIA, OTA AJOISSA YHTEYTTÄ!!! 23.1.2005 KyAMK - TiRak, syksy 2005 1 Kynätehtävä 1: Puurakenteet a) Kuinka monta NULL-pointteri-lasta on puussa, jossa on n alkiota? b) Mikä on pienin ja mikä suurin mahdollinen määrä solmuja puussa, jonka korkeus on h? Perustele vastauksesi, pelkät lukuarvot eivät riitä. Huom! Puu ei siis välttämättä ole binääripuu 23.1.2005 KyAMK - TiRak, syksy 2005 2
Kynätehtävä 2: Binääripuun läpikäynti Jos binääripuun kaikkien solmujen sisältö on erilainen, voidaan puu esittää myös taulukon avulla luettelemalla solmujen vasen ja oikea lapsi. Alla on eräs binääripuu: lapset solmu vasen oikea e: g d a: f e d: s y f: - t g: - z t: c x Solmu a on puun juuri. Luettele solmujen läpikäyntijärjestys, kun puu käydään läpi a) esijärjestyksessä (preorder) b) sisäjärjestyksessä (inorder) c) jälkijärjestyksessä (postorder) d) tasojärjestyksessä (level order) 23.1.2005 KyAMK - TiRak, syksy 2005 3 Kynätehtävä 3: Binäärinen hakupuu Lisää tyhjään binääriseen hakupuuhun (BST) (aakkos)järjestyksessä alla olevat alkiot. Mahdolliset yhtä suuret alkiot sijoitetaan oikeanpuoleiseen haaraan: g n d h d x x s t c a x a a) Millainen puu on, kun kaikki alkiot on lisätty? b) Poista puun juurialkio algoritmilla, joka käyttää poistettavan alkion oikean puoleista alipuuta (Näin tehty jaetussa BST-koodissa). Millainen puu on poiston jälkeen? 23.1.2005 KyAMK - TiRak, syksy 2005 4
Kynätehtävä 4: Minimikeko Syötteestä 5 9 0 8 1 7 2 4 muodostetaan minimikeko (heap) lisäämällä luvut yksitellen aluksi tyhjään kekoon (algoritmi insert() jaetussa koodissa). a) Esitä keko jokaisen lisäyksen jälkeen puuna sekä lopullinen keko taulukkona. b) Esitä keko sekä puuna että taulukkona seuraavien operaatioiden jälkeen (erillisiä, molemmissa lähtötilanne a)-kohdan tulos): - suoritetaan kerran operaatio delmin() - minimialkio korvataan alkiolla 6 23.1.2005 KyAMK - TiRak, syksy 2005 5 Ohjelmointiohjeita Jos käytät jaettua koodia (List, BST, AVL, PQ), menettele niin kuin on menetelty demo-ohjelmissa: ohjelma toteutettu projektina, jonka osina oma ohjelma, ja jaettu koodi (bst.c, avl.c, pq.c), sekä funktioiden prototyypit omaan ohjelmaan.htiedostona (bst.h, avl.h, pq.h). Vältä siis sitä, että kopioit jaettua koodia oman ohjelmasi jatkoksi samaan tiedostoon. Jos käytät Javaa tai C++:aa oliotyylisesti, mieluimmin sijoita työkalut (Bst.java tai bst.cpp ym.) ja niitä hyödyntävä sovellus eri tiedostoon. 23.1.2005 KyAMK - TiRak, syksy 2005 6
Ohjelmointitehtävä 1: BST:n alkioiden lukumäärä Kirjoita seuraavat metodit tai funktiot: a)countnodes(), joka laskee BST:n alkioiden (nodet) lukumäärän. Funktion olennainen osa lienee rekursiivinen kutsu return countnodes(t.left) + countnodes(t.right)+ 1. b)countleaves(), joka laskee BST:n lehtien (terminal node) lukumäärän. Kirjoita lopuksi pieni testiohjelma, joka konstruoi BST:n. Käytä puun datana kokonaislukuja. Tulosta lopuksi puu siten, että kokonaisluvut ovat suuruusjärjestyksessä pienimmästä suurimpaan. 23.1.2005 KyAMK - TiRak, syksy 2005 7 Ohjelmointitehtävä 2: Lukujonon satunnainen järjestys Kirjoita funktio, joka generoi n-alkioiseen taulukkoon kokonaisluvut 1, 2, 3,..., n satunnaisessa järjestyksessä (siis muodostaa kyseisten lukujen jonkin permutaation). Eräs menetelmä voisi olla seurava: Käytetään 2 taulukkoa, toiseen arvotaan luvut ja toisella estetään jo arvotun toistuminen. Jälkimmäinen nollataan aluksi, ja kun luku k on saatu ensimmäisen kerran, muutetan taulukon k:s alkio esim. 1:ksi. Arvottu luku k hyväksytään vain jos aputaulukon k:s alkio on 0. Menetelmä ei ole nopein mahdollinen. Esimerkiksi luvut 1, 2,..., n voidaan sijoittaa aluksi taulukkoon järjestyksessä. Permutaatio suoritetaan sitten vaihtamalla (swap) jokainen luku vuorollaan taulukosta arvotun toisen luvun kanssa. Saat käyttää muutakin menetelmää, toivottavasti parempaa kuin edellä kuvatut. Koeta lisäksi arvioida käyttämäsi algoritmin suoritusaika, tulos O(n)- muodossa. 23.1.2005 KyAMK - TiRak, syksy 2005 8
Ohjelmointitehtävä 3: BST:n korkeus Tässä tehtävässä tarvitaan edellisen tehtävän funktiota. Selvitetään kokeellisesti, mikä on BST:n keskimääräinen korkeus. Tämä tehdään seuraavasti: luodaan BST tehtävän 3 satunnaislukutaulukon perusteella ja lasketaan sen korkeus h(n). Tämä toistetaan m kertaa. Lopuksi tulostetaan saatujen korkeuksien keskiarvo. Tulosta myös esiintyneistä korkeuksista pienin ja suurin. Täydellisimmin BST voi olla balansoitu, jos n on muotoa 2 k -1, jolloin BST:n minimikorkeus on k - 1. Käytä n:nä tällaista lukua, esim. 1023. Luvun m tulee olla melko suuri, mielellään vähintään 1000, jotta tuloksen tilastollinen virhe ei olisi merkitsevä. Koska BST muodostetaan dynaamisesti, muisti saattaa loppua kesken, jollei puuta tuhota ennen uuden muodostamista. 23.1.2005 KyAMK - TiRak, syksy 2005 9 Ohjelmointitehtävä 4: BST:n käyttöä Käytä BST-puuta merkkijonojen järjestämisessä. Ota dataksi jokin tekstitiedosto, muunna se lower case merkkijonoiksi ja sijoita merkkijonot BST-puuhun (älä myöskään ota välimerkkejä mukaan). Tulosta tämän jälkeen merkkijonot aakkosjärjestyksessä. Tekstitiedostossa on syytä olla ainakin tuhat sanaa, jotta puusta tulee järkevä. Materiaalina voit käyttää vaikkapa alice29.txt tiedostoa, jonka löydät OAK:n Yhteiset-verkkolevyltä. Ota ko. teoksesta ensi alkuun vaikkapa 1.luku ja kokeile sen jälkeen koko tekstillä. Itse merkkijonoja ei siis ehkä kannata laittaa puuhun, vaan käyttää jonkinlaista indeksointia Yksi (ei välttämättä kovin hyvä) tapa voisi olla laskea merkkijonoille lukuarvo seuraavasti: n i= 0 k( i)*26 n i Tässä n on siis merkkien suurin mahdollinen määrä ja i on indeksi merkkijonossa sekä k(i):n pitää antaa arvo kirjaimelle (a z=1 26). Huono puoli tässä laskennassa on, että pitää tietää pisimmän merkkijonon pituus etukäteen... 23.1.2005 KyAMK - TiRak, syksy 2005 10