Tietorakenteet, laskuharjoitus 6,

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

Hakupuut. tässä luvussa tarkastelemme puita tiedon tallennusrakenteina

Binäärihaun vertailujärjestys

TKT20001 Tietorakenteet ja algoritmit Erilliskoe , malliratkaisut (Jyrki Kivinen)

A TIETORAKENTEET JA ALGORITMIT

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

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

Tietorakenteet, laskuharjoitus 7, ratkaisuja

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

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

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.

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

Algoritmit 2. Luento 7 Ti Timo Männikkö

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

CS-A1140 Tietorakenteet ja algoritmit

Kierros 4: Binäärihakupuut

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

Informaatioteknologian laitos Olio-ohjelmoinnin perusteet / Salo

Algoritmit 1. Luento 7 Ti Timo Männikkö

Algoritmit 2. Luento 2 To Timo Männikkö

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 2. Luento 5 Ti Timo Männikkö

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

Olio-ohjelmointi Javalla

Algoritmit 2. Luento 2 Ke Timo Männikkö

Algoritmit 1. Luento 8 Ke Timo Männikkö

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

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

Algoritmit 2. Luento 5 Ti Timo Männikkö

Mikä yhteyssuhde on?

Tietorakenteet, laskuharjoitus 3, ratkaisuja

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

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

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

Algoritmit 1. Luento 6 Ke Timo Männikkö

14 Tasapainotetut puurakenteet

Ohjelmoinnin jatkokurssi, kurssikoe

3. Binääripuu, Java-toteutus

A TIETORAKENTEET JA ALGORITMIT

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

58131 Tietorakenteet Erilliskoe , ratkaisuja (Jyrki Kivinen)

Ohjelmointi 2 / 2010 Välikoe / 26.3

Kompositio. Mikä komposition on? Kompositio vs. yhteyssuhde Kompositio Javalla Konstruktorit set-ja get-metodit tostring-metodi Pääohjelma

B + -puut. Kerttu Pollari-Malmi

Ohjelmointitaito (ict1td002, 12 op) Kevät Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma.

1.1 Tavallinen binäärihakupuu

Tietorakenteet, laskuharjoitus 4,

JAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++?

Sisältö. 2. Taulukot. Yleistä. Yleistä

Sisältö. 22. Taulukot. Yleistä. Yleistä

Tietorakenteet, laskuharjoitus 7,

Algoritmit 1. Luento 5 Ti Timo Männikkö

18. Abstraktit tietotyypit 18.1

ALGORITMIT 1 DEMOVASTAUKSET KEVÄT 2012

Ohjelmointitaito (ict1td002, 12 op) Kevät Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen

Algoritmit 2. Luento 4 To Timo Männikkö

Sisällys. 18. Abstraktit tietotyypit. Johdanto. Johdanto

Metodien tekeminen Javalla

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

Rajapinta (interface)

Java-kielen perusteet

Tietorakenteet, laskuharjoitus 4,

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op. Tietorakenneluokkia 2: HashMap, TreeMap

Tietorakenteet, laskuharjoitus 1,

Ohjelmointi 2 / 2008 Välikoe / Pöytätestaa seuraava ohjelma.

Tietorakenteet, laskuharjoitus 2,

4. Joukkojen käsittely

Tietorakenteet ja algoritmit

811312A Tietorakenteet ja algoritmit, , Harjoitus 5, Ratkaisu

Tietorakenteet (syksy 2013)

1 Puu, Keko ja Prioriteettijono

Luku 4. Tietorakenteet funktio-ohjelmoinnissa. 4.1 Äärelliset kuvaukset

TIETORAKENTEET JA ALGORITMIT

Harjoitus Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

Luokan sisällä on lista

Algoritmit 2. Luento 4 Ke Timo Männikkö

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

7. Oliot ja viitteet 7.1

13. Loogiset operaatiot 13.1

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

Tietorakenteet. JAVA-OHJELMOINTI Osa 5: Tietorakenteita. Sisällys. Merkkijonot (String) Luokka String. Metodeja (public)

Olion elinikä. Olion luominen. Olion tuhoutuminen. Olion tuhoutuminen. Kissa rontti = null; rontti = new Kissa();

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

811312A Tietorakenteet ja algoritmit, , Harjoitus 7, ratkaisu

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

Luokka Murtoluku uudelleen. Kirjoitetaan luokka Murtoluku uudelleen niin, että murtolukujen sieventäminen on mahdollista.

7. Tasapainoitetut hakupuut

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

58131 Tietorakenteet ja algoritmit (syksy 2015)

Algoritmit 2. Luento 6 To Timo Männikkö

Java-kielen perusteita

Rinnakkaisohjelmointi kurssi. Opintopiiri työskentelyn raportti

public static void main (String [] args)

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

Tietorakenteet ja algoritmit - syksy

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

811312A Tietorakenteet ja algoritmit II Perustietorakenteet

Pino S on abstrakti tietotyyppi, jolla on ainakin perusmetodit:

Listarakenne (ArrayList-luokka)

Transkriptio:

Tietorakenteet, laskuharjoitus, 23.-2.1 1. (a) Kuvassa 1 on esitetty eräät pienimmistä AVL-puista, joiden korkeus on 3 ja 4. Pienin h:n korkuinen AVL-puu ei ole yksikäsitteinen juuren alipuiden keskinäisen järjestyksen tai avaimien suhteen. Kuvasta 1a kuitenkin havaitaan, että pienimmässä kolmen korkuisessa AVL-puussa on juuren alipuina pienin yhden ja kahden korkuinen AVL-puu. 2 Vastaava 13 pätee 22 myös pienimmälle neljän korkuiselle AVL-puulle, sen juuren alipuut ovat pienimmät kahden ja kolmen korkuiset AVL-puut. 1 3 10 17 21 33 55 77 2 22 7 101 1 150 17 22 2 22 2 13 2 13 22 22 107 2 22 33 55 77 77 1 3 1 10 17 21 33 55 77 7 101 (a) Pienin AVL puu, jonka korkeus on 3 150 (b) Pienin AVL puu, 101 jonka korkeus on 4 Kuva 1: Pienimpiä mahdollisia AVL-puita 150 107 1 1 Kuvassa 17 2 on esitetty suurimmat mahdolliset AVL-puut, joiden korkeus on 3 ja 4. Täydellinen puu on erityisen 2 tasapainoinen 13 22 puuja se täyttää 107 myös 2 AVLehdon, joten suurin h:n korkuinen AVL-puu on h:n korkuinen täydellinen puu. 10 17 11 1 3 10 17 21 33 55 77 102 10 11 133 154 12 177 221 33 55 77 101 107 1 2 2 1 3 150 10 13 10 17 22 11 17 21 33 55 77 102 10 11 133 154 12 177 221 (a) Suurin AVL puu, jonka korkeus on 3 101 101 150 1 17 2 22 2 13 22 107 2 10 11 1 3 10 17 21 33 55 77 102 77 10 11 133 154 12 177 221 (b) Suurin AVL puu, jonka korkeus on 4 Kuva 2: Suurimpia mahdollisia 150 AVL-puita (b) Kuvassa 3 on esitetty puu, jonka 1 täytyi osoittaa 17 toteuttavan AVL-ominaisuus. Kuvan yhteyteen on merkitty alipuiden korkeudet kunkin solmun vasemmalle 2 13 22 107 1 1 101 150

puolelle. Puu on AVL-puu jos kaikille solmuille n pätee: Height(n.left) Height(n.right) 1 Siis jokaisen solmun vasemman ja oikean alipuun korkeuksien erotus on itseisarvoltaan -1, 0 tai 1. Laskemalla jokaisen solmun alipuiden korkeuden erotuksen havaitaan, että kuvassa 3 esiintyvä puu on AVL-puu. 21 10 30 13 24 55 Kuva 3: Puu, jonka solmujen yhteyteen on merkitty niistä lähtevien alipuiden korkeus 2. (a) Kuvassa 4 on esitetty annettujen avainten lisäys AVL-puuhun. Ensin lisätään avaimet, ja (kuvat 4a, 4b ja 4c). Viimeisen lisäyksen jälkeen puu on epätasapainossa. Se saadaan jälleen tasapainoon kiertämällä avaimen solmua oikealle (kuva 4d). Lisätään avaimet ja (kuvat 4e ja 4f). Jälkimmäinen lisäys saa puun epätasapainoon, joka korjataan suorittamalla avaimen solmuun vasen-oikea kaksoiskierto. Ensin kierretään avaimen solmu vasemmalle (kuva 4g), jonka jälkeen kierretään avaimen solmu oikealle (kuva 4h). Tämän jälkeen lisätään puuhun (kuva 4i), joka saa puun juuren epätasapainoon. Puun juurta käännetään oikealle (kuva 4j). Viimeisenä puuhun lisätään ja. Kumpikaan lisäyksistä ei vaikuta puun tasapainoon, joten kiertoja ei tarvita enempää. (b) Kuvassa 5 on esitetty edellisen tehtävän avainten lisääminen AVL-puuhun käänteisessä järjestyksessä. Alussa puuhun lisätään avaimet, ja (kuvat 5a, 5b ja 5c). Viimeisen lisäyksen jälkeen puun juuri on epätasapainossa. Puu saadaan tasapainoiseksi kiertämällä juurta oikealle (kuva 5d). Tämän jälkeen puuhun lisätään avaimet ja (kuvat 5e ja 5f). Nyt avaimen solmu on epätasapainossa. Se saadaan korjattua oikea-vasen kaksoiskierrolla. Ensin kierretään avaimen solmua oikealle (kuva 5g) jonka jälkeen avaimen solmu kierretään vasemmalle (kuva 5h). Tämän jälkeen lisätään avaimet ja (kuvat 5i ja 5j), jonka jälkeen avaimen solmu on epätasapainossa. Tilanne korjataan tekemällä vasen-oikea kaksoiskierto solmuun (kuvat 5k ja 5l). Viimeiseksi lisätään (kuva 5m). 2

3 4 (a) (b) (c) (d) (e) 1 1 2 1 2 (f) (g) (h) 1 (i) (j) (k) (l) Kuva 4: Avaimien,,,,,,, lisäys AVL-puuhun 3

9 (a) (b) (c) (d) (e) 7 1 (f) (g) (h) (i) (j) (k) 9 (l) (m) Kuva 5: Avaimien,,,,,,, lisäys AVL-puuhun 4

3. (a) Kuvassa aloitetaan poistojen sarja kuvan 4l tilanteesta. Ensin poistetaan, jonka yhteydessä solmu asetetaan juuren vasemmaksi alipuuksi (kuva a). Tämän seurauksena juuri tulee epätasapainoon, mikä korjataan kiertämällä juurta vasemmalle (kuva b). Seuraavaksi poistetaan (kuva c), jonka seurauksena juuri on jälleen epätasapainossa. Tilanteesta selvitään suorittamalla vasen-oikea kaksoiskierto juureen. Ensin kierretään solmu vasemmalle (kuva d), jonka jälkeen juuri kierretään oikealle (kuva e). Tämän jälkeen poistetaan tavalliseen binäärihakupuun poiston tapaan (kuva f). Siinä korvataan ensin avaimen solmun avain oikean alipuun pienimmällä avaimella. Varsinainen poisto kohdistuu korvaavan avaimen () solmuun. Lopuksi poistetaan (kuva g), jonka poisto ei horjuta AVL-puun tasapainoehtoa. (b) Kuvassa 7 aloitetaan poistojen sarja kuvan 5m tilanteesta. Ensin poistetaan ja (kuvat 7a ja 7a). Jälkimmäinen poisto saa juuren epätasapainoon. Tilanne korjataan kiertämällä juurta vasemmalle (kuva 7c). Tämän jälkeen poistetaan, joka ei eroa tavallisesta binäärihakupuun poistooperaatiosta lainkaan (kuva 7d). Vimeiseksi poistetaan (kuva 7e), joka saa jälleen juuren epätasapainoon. Tilanne korjataan kiertämällä juurta oikealle (kuva 7f). 5

(a) (b) (c) (d) (e) (f) (g) Kuva : Avaimien,, ja poisto kuvan 4l tilanteesta aloitettuna

(a) (b) (c) (d) (e) (f) Kuva 7: Avaimien,, ja poisto kuvan 5m tilanteesta aloitettuna 7

4. Ohessa on binääripuu toteutettuna Javalla. Luokan main-metodissa on puun toiminnan testailua. class BTree { private long key; private BTree left; private BTree right; public BTree(long value) { this.key = value; this.right = null; this.left = null; public void setright(btree right) { this.right = right; public BTree getright() { return this.right; public void setleft(btree left) { this.left = left; public BTree getleft() { return this.left; /* Insert-operaatio olisi luonnollisinta kirjoittaa rekursiivisesti, * mutta säästääksemme muistia teemme siitä iteratiivisen version. */ public void insert(long key) { boolean inserted = false; BTree node = new BTree(key); BTree curr = this; while(!inserted) { if (key <= curr.key) { if (curr.left == null) { curr.left = node; inserted = true; else { curr = curr.left;

else { if (curr.right == null) { curr.right = node; inserted = true; else { curr = curr.right; /* Tämäkin olisi tehokkaampi iteratiivisena versiona, mutta näytetään * miten tämä (ja edellinen) voidaan toteuttaa rekursiivisena. */ public boolean search(long key) { if (key == this.key) return true; else if (key < this.key && this.left!= null ) return this.left.search(key); else if ( this.right!= null ) return this.right.search(key); else return false; public long height() { long left = (this.left == null)? 0 : this.left.height(); long right = (this.right == null)? 0 : this.right.height(); return Math.max(left, right) + 1; public void print() { if ( this.left!= null ) this.left.print(); System.out.print(this.key + " "); if ( this.right!= null ) this.right.print(); public static void main(string[] args) { int kertaa = 100; if (args.length > 0) kertaa = Integer.parseInt(args[0]); 9

long eka = (long) (Long.MAX_VALUE * Math.random()); BTree puu = new BTree(eka); for (int i = 0; i < kertaa; i++) puu.insert((long) (Long.MAX_VALUE * Math.random()) ); puu.print(); System.out.println(); long num = (long) (Long.MAX_VALUE * Math.random()); if (puu.search(num)) System.out.println(num + " löytyi puusta."); else System.out.println(num + " ei löytynyt puusta."); if (puu.search(eka)) System.out.println(eka + " löytyi puusta."); else System.out.println(eka + " ei löytynyt puusta."); System.out.println("Puun korkeus on " + puu.height()); System.out.println("Vertailun vuoksi: kaksikantainen logaritmi luvusta " + kertaa + " on "+ Math.log(kertaa)/Math.log(2)); 100 Binääripuun korkeus lisättäessä n avainta korkeus log 2 0 0 40 20 0 5e+0 1e+07 1.5e+07 2e+07 2.5e+07 3e+07 3.5e+07 4e+07 4.5e+07 5e+07 n Kuva : Puun korkeus lisättäessä n satunnaista avainta 5. (a) Kuvassa on kaksikantaisen logaritmin ja puun korkeuden kuvaajat kun puuhun on lisätty n satunnaista avainta. Kuvaajasta havaitaan, että kun puuhun 10

lisätään satunnaisia avaimia ei sen korkeus eroa kovinkaan paljon logaritmifunktion arvoista. Itse asiassa näyttääkin, puun korkeudelle h pätisi n:n satunnaisen avaimen lisäyksessä h 3 log 2 n = O(log n). Tietenkään tämä ei ole vielä validi perustelu, mutta voidaan osoittaa, että tämänlaisessa tilanteessa puun korkeuden odotusarvo on logaritminen puun avainten lukumäärän suhteen. (b) Kuvissa 9, 10 ja 11 on esitetty oman puumme vertailuja Javan kirjastoista löytyvään TreeSettiin. Yllättävästi tasapainoittamaton puumme oli nopeampi sekä satunnaisissa lisäyksissä, että hauissa. Tämä selittyy osittain siitä, ettei tasapainoittamatonkaan puu kasva kovinkaan korkeaksi jos avaimet lisätään satunnaisesti. Lisäysten nopeus selittyy sillä, ettei omassa puutoteutuksessamme tarvittu tasapainotusoperaatioita. Hakujen nopeutta selittää se, että puumme on tarpeeksi matala. Luultavasti TreeSettiä hidastaa hiukan sen geneerinen toteutus, joka pakottaa sen käyttämään Long-olioita primitiivisen long-tietotyypin sijasta. Tasapainotetun puun suurin etu nähdään etsittäessä avaimia puusta, johon avaimet on lisätty järjestyksessä. Tässä tapauksessa oma tasapainoittamaton puumme surkastuu tavalliseksi listaksi, jossa haut ovat hitaita. Kesto lisättäessä n satunnaista avainta 00 oma puu Javan TreeSet 1000 00 00 400 200 0 100000 200000 300000 400000 500000 00000 700000 00000 900000 1e+0 n Kuva 9: Kesto lisättäessä n satunnaista avainta. Vakioaikaiset min- ja max-operaatiot voidaan toteuttaa säilyttämällä puun yhteydessä osoittimia sen pienimpään ja suurimpaan avaimeen. Näiden tallettaminen lisää puun operaatioita ainoastaan vakioajalla, koska ehdot voidaan tarkistaa yksinkertaisella ehtolausekkeella. Vakioaikaiset seuraaja- ja edeltäjä-operaatiot saadaan tallettamalla jokaisen solmun yhteyteen viite sen avaimen seuraajan ja edeltäjän sisältäviin solmuihin. Binääripuu- 11

500 n hakua 1000000:n satunnaisen avaimen puuhun oma puu Javan TreeSet 400 300 200 100 0 50000 100000 150000 200000 250000 300000 350000 400000 450000 500000 n Kuva 10: Kesto haettaessa n satunnaista avainta 1000000:n satunnaisessa järjestyksessä lisätyn avaimen puusta 1000 n hakua 20000:n järjestyksessä lisätyn avaimen puuhun oma puu Javan TreeSet 00 00 400 200 0 1000 2000 3000 4000 5000 000 7000 000 9000 10000 n Kuva 11: Kesto haettaessa n avainta 20000:n järjestyksessä lisätyn avaimen puusta

ta, jossa on tavallisten left- ja right-viitteiden lisäksi viitteet solmun seuraajaan ja edeltäjään kutsutaan langoitetuksi (engl. threaded). Langoitus ei lisää operaatioiden aikavaativuutta kuin vakiokertoimella. Lisättäessä binäärihakupuuhun avainta, sen seuraaja ja edeltäjä tulevat vastaan hakupolulla, joten langoituksen toteuttamiseksi ei tarvitse toteuttaa edes ylimääräisiä hakuja puuhun. Näiden muutoksien huonona puolena on lisääntynyt muistin tarve ja aavistuksen hidastuvat lisäys- ja poisto-operaatiot. Jos puun yksi viite vie tilaa 4 tavua ja avain vie tilaa c tavua, niin ilman edeltäjä- ja seuraaja-osoittimia n:n alkion puu vie tilaa (+c)n+ tavua. Lausekkeen tulee viitteestä juureen sekä min- ja max-viitteistä. Jos puuhun talletetaan lisäksi viitteet edeltäjään ja seuraajaan, niin n:n alkion puu vie tilaa (1 + c)n +. Siis itse rakenteen koko kaksinkertaistuu! Huomaa, että tässä tarkastelussa käytetyt arvot eivät kuvasta Javan todellisuutta, koska Javassa olioiden yhteyteen talletetaan paljon muutakin tavaraa. Ohessa on vielä langoitetun binääripuun toteuts Javana. class ThreadedBTree { private class BTnode { public BTnode left; public BTnode right; public BTnode succ; public BTnode pred; public long key; public BTnode(long key) { this.key = key; this.succ = null; this.pred = null; this.left = null; this.right = null; public BTnode(long key, BTnode succ, BTnode pred) { this.key = key; this.succ = succ; this.pred = pred; this.left = null; this.right = null; private BTnode min; private BTnode max; 13

private BTnode root; public ThreadedBTree(long key) { BTnode node = new BTnode(key); this.min = node; this.max = node; this.root = node; public void insert(long key) { BTnode succ, pred, curr; BTnode node = new BTnode(key); boolean inserted = false; succ = pred = null; curr = this.root; /* Väistämättä avaimen seuraaja ja edeltäjä * tulevat vastaan matkan varrella kun etsitään * kohtaa johon lisätä. */ while(!inserted) { /* Huomaa ettemme hyväksy tässä avainten duplikaatteja. */ if ( (succ == null curr.key < succ.key) && key < curr.key) succ = curr; if ( (pred == null curr.key > pred.key) && key > curr.key) pred = curr; if( key < curr.key ) { if (curr.left == null) { curr.left = node; inserted = true; else { curr = curr.left; else if ( key > curr.key ) { if (curr.right == null) { curr.right = node; inserted = true; else { curr = curr.right; else return; if (pred!= null) { 14

node.pred = pred; pred.succ = node; if (succ!= null) { node.succ = succ; succ.pred = node; if (this.min.key > key) this.min = node; if (this.max.key < key) this.max = node; /* Koska jouduimme ottamaan mukaan sisäluokan joudumme * hoitamaan tavallisen puun rekursion käsin käyttäen pinoa, * kirjoittamaan metodit sisäluokalle tai käyttämällä * staattisia metodeja. Rekursion käyttäminen on puiden * tapauksessa luonnollista, joten tässä on päätetty * ohittaa hankaluudet sen avulla. */ public void print_default() { print_helper(this.root); private static void print_helper(btnode solmu) { if (solmu == null) return; print_helper(solmu.left); System.out.print(solmu.key + " "); print_helper(solmu.right); public void print_threaded_asc() { BTnode curr = this.min; while(curr!= null) { System.out.print(curr.key + " "); curr = curr.succ; public static void main(string[] args) { 15

ThreadedBTree puu = new ThreadedBTree(0); for (int i = 0; i < 20; i++) puu.insert((long) (100*Math.random())); puu.print_default(); System.out.println(); puu.print_threaded_asc(); 1