CS-A1140 Tietorakenteet ja algoritmit

Samankaltaiset tiedostot
Kierros 3: Puut. Tommi Junttila. Aalto University School of Science Department of Computer Science

Hakupuut. tässä luvussa tarkastelemme puita tiedon tallennusrakenteina

Algoritmit 2. Luento 2 To Timo Männikkö

Algoritmit 2. Luento 2 Ke Timo Männikkö

Algoritmit 1. Luento 8 Ke Timo Männikkö

Algoritmi on periaatteellisella tasolla seuraava:

Kierros 4: Binäärihakupuut

A TIETORAKENTEET JA ALGORITMIT

CS-A1140 Tietorakenteet ja algoritmit

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

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

Algoritmit 2. Luento 4 To Timo Männikkö

Algoritmit 1. Luento 7 Ti Timo Männikkö

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

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

811312A Tietorakenteet ja algoritmit III Lajittelualgoritmeista

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 7 Ti Timo Männikkö

Algoritmit 2. Luento 4 Ke Timo Männikkö

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

4. Joukkojen käsittely

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

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

Algoritmit 2. Luento 5 Ti Timo Männikkö

TKT20001 Tietorakenteet ja algoritmit Erilliskoe , malliratkaisut (Jyrki Kivinen)

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

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

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

811312A Tietorakenteet ja algoritmit V Verkkojen algoritmeja Osa 2 : Kruskalin ja Dijkstran algoritmit

1 Puu, Keko ja Prioriteettijono

Algoritmit 2. Luento 5 Ti Timo Männikkö

58131 Tietorakenteet Erilliskoe , ratkaisuja (Jyrki Kivinen)

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

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.

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

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

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

Luku 7. Verkkoalgoritmit. 7.1 Määritelmiä

Algoritmit 2. Luento 6 To Timo Männikkö

Tietorakenteet ja algoritmit

V. V. Vazirani: Approximation Algorithms, luvut 3-4 Matti Kääriäinen

Johdatus graafiteoriaan

811312A Tietorakenteet ja algoritmit, , Harjoitus 5, Ratkaisu

Fibonacci-kasoilla voidaan toteuttaa samat operaatiot kuin binomikasoilla.

Algoritmit 2. Demot Timo Männikkö

Binäärihaun vertailujärjestys

Algoritmit 2. Luento 3 Ti Timo Männikkö

Algoritmit 1. Luento 6 Ke Timo Männikkö

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

Algoritmit 2. Luento 9 Ti Timo Männikkö

Olkoon seuraavaksi G 2 sellainen tasan n solmua sisältävä suunnattu verkko,

Algoritmit 2. Luento 3 Ti Timo Männikkö

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

Algoritmit 2. Luento 6 Ke Timo Männikkö

Algoritmit 1. Luento 5 Ti Timo Männikkö

58131 Tietorakenteet ja algoritmit Uusinta- ja erilliskoe malliratkaisut ja arvosteluperusteet

Tietorakenteet, laskuharjoitus 6,

verkkojen G ja H välinen isomorfismi. Nyt kuvaus f on bijektio, joka säilyttää kyseisissä verkoissa esiintyvät särmät, joten pari

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

ALGORITMIT 1 DEMOVASTAUKSET KEVÄT 2012

Algoritmit 1. Luento 9 Ti Timo Männikkö

Eräs keskeinen algoritmien suunnittelutekniikka on. Palauta ongelma johonkin tunnettuun verkko-ongelmaan.

10. Painotetut graafit

Pienin virittävä puu (minimum spanning tree)

B + -puut. Kerttu Pollari-Malmi

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

Tietorakenteet ja algoritmit - syksy

Tietorakenteet, laskuharjoitus 7, ratkaisuja

A TIETORAKENTEET JA ALGORITMIT

Kysymyksiä koko kurssista?

Tietorakenteet, laskuharjoitus 3, ratkaisuja

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

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

useampi ns. avain (tai vertailuavain) esim. opiskelijaa kuvaavassa alkiossa vaikkapa opintopistemäärä tai opiskelijanumero

811312A Tietorakenteet ja algoritmit II Perustietorakenteet

Algoritmit 1. Luento 13 Ma Timo Männikkö

(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ä.

Algoritmit 1. Luento 12 Ti Timo Männikkö

811312A Tietorakenteet ja algoritmit, , Harjoitus 5, Ratkaisu

Algoritmit 1. Luento 12 Ke Timo Männikkö

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

Johdatus graafiteoriaan

Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari Korhonen

Luku 8. Aluekyselyt. 8.1 Summataulukko

Ohjelmoinnin perusteet Y Python

1.1 Tavallinen binäärihakupuu

Tarkennamme geneeristä painamiskorotusalgoritmia

Algoritmit 2. Luento 14 Ke Timo Männikkö

Datatähti 2019 loppu

7. Tasapainoitetut hakupuut

TIEA241 Automaatit ja kieliopit, kevät Antti-Juhani Kaijanaho. 2. helmikuuta 2012

811312A Tietorakenteet ja algoritmit Kertausta jälkiosasta

ja λ 2 = 2x 1r 0 x 2 + 2x 1r 0 x 2

A ja B pelaavat sarjan pelejä. Sarjan voittaja on se, joka ensin voittaa n peliä.

= 5! 2 2!3! = = 10. Edelleen tästä joukosta voidaan valita kolme särmää yhteensä = 10! 3 3!7! = = 120

3. Binääripuu, Java-toteutus

isomeerejä yhteensä yhdeksän kappaletta.

Algoritmit 2. Luento 10 To Timo Männikkö

811312A Tietorakenteet ja algoritmit Kertausta jälkiosasta

Valitaan alkio x 1 A B ja merkitään A 1 = A { x 1 }. Perinnöllisyyden nojalla A 1 I.

Transkriptio:

CS-A1140 Tietorakenteet ja algoritmit Kierros 3: Puut Tommi Junttila Aalto-yliopisto Perustieteiden korkeakoulu Tietotekniikan laitos Syksy 2016

Sisältö Puut yleisesti Matemaattinen määrittely Puiden läpikäynti (esi-, jälki-, sisä- ja tasojärjestykset) Puihin pohjautuvia tietorakenteita ja algoritmeja Keot ja prioriteettijonot Erilliset joukot eli yhdistä-ja-etsi (engl. union-find) 2/61

Materiaali kirjassa Introduction to Algorithms, 3rd ed. (online via Aalto lib): Binääripuut: Liite B5 Puiden esitysmuodoista: Kappale 10.4 Keot: Luku 6 Yhdistä-ja-etsi: Luku 21 3/61

Samantapaista materiaalia muualla: Yhdistä-ja-etsi: kappale 1.5 kirjassa Algorithms, 4th ed. Keot OpenDSA-kirjassa Yhdistä-ja-etsi OpenDSA-kirjassa Muita linkkejä: MIT 6.006 OCW video on heaps and heap sort 4/61

Puut 5/61

Puita ollaan tavattu aiemminkin: Rekursiopuut Ohjelmointi 2- ja tällä kurssilla Lausekkeiden jäsennyspuut oliodiagrammien muodossa Ohjelmointi 2-kurssin Expressions osuudessa rekursiokierroksella... Pikajärjestämisalgoritmin kutsupuu 0 1 2 3 4 5 6 7 input 21 17 19 1 21 7 2 20 partition(0,7) 17 19 1 7 2 20 21 21 quicksort(0,4) quicksort(6,7) 17 19 1 7 2 21 21 partition(0,4) partition(6,7) 1 2 17 7 19 21 21 quicksort(2,4) 17 7 19 partition(2,4) 17 7 19 quicksort(2,3) 17 7 partition(2,3) 7 17 Lausekkeen (2.0x + y) jäsennyspuu oliodiagrammina Num value = 2.0 Multiply left right Negate expr Add left right Var name = "x" Var name = "y" sorted 1 2 7 17 19 20 21 21 6/61

Puut ovat yleinen käsite ja myös tietorakenne tietotekniikassa ja tietojenkäsittelytieteessä Tällä kierroksella tarkastellaan puita 1. matemaattisina olioina ja 2. tietorakenteena, jota voidaan käyttää toteuttamaan muita tietorakenteita ja algoritmeja Toisen kohdan esimerkkeinä tarkastellaan kuinka prioriteettijonot voidaan toteuttaa kekoina eli puina, joilla on tiettyjä myöhemmin määriteltäviä ominaisuuksia, ja erillisten joukkojen esittämistä ja yhdistämistä puiden avulla Puita käsitellään myös tulevilla kierroksilla 7/61

Perusmäärittelyjä Puut ovat verkkojen aliluokka 1 Suuntaamaton verkko on pari (V, E), missä V on (yleensä äärellinen) joukko solmuja (engl. vertex, node) ja E on joukko kaaria solmujen välillä eli joukko pareja muotoa {u,v} siten, että u,v V ja u v 2 Esimerkki: Tarkastellaan verkkoa (V, E) missä solmut ovat V = {a,b,c,d,e,f,g,h} ja e c g kaaret ovat E = {{a,b},{a,c},{a,e},{a,f }, {b,f },{e,f },{c,d},{c,g},{d,g}}. a d Graafisesti verkko on esitetty oikealla; solmut ovat ympyröitä ja kaaret niitä yhdistäviä viivoja f b 1 Palaamme verkkoihin ja verkkoalgoritmeihin myöhemmin kurssilla 2 Silmukat eli kaaret solmun ja sen itsensä välillä eivät siis ole nyt sallittuja 8/61

polku solmusta v 0 solmuun v k on sekvenssi (v 0,v 1,...,v k ) solmuja siten, että {v i,v i+1 } E jokaiselle i = 0,1,...k 1; polun pituus on k Solmu v on saavutettavissa solmusta u jos on olemassa polku solmusta u solmuun v. Huomaa, että jokainen solmu u on saavutettavissa itsestään koska (u) on 0 askeleen pituinen polku Polku on yksinkertainen jos kaikki solmut siinä ovat erillisiä Verkko on yhtenäinen jos jokainen solmu siinä on saavutettavissa jokaisesta muusta solmusta Esimerkki: Oikealla oleva verkko sisältää (ei-yksinkertaisen) polun (a,c,d,g,c,d) solmusta a solmuun d sisältää yksinkertaisen 2 askeleen polun (a, c, d) solmusta a solmuun d on yhtenäinen mutta kaaren {a, c} poistaminen tekisi siitä ei-yhtenäisen e f a c b g d 9/61

Sykli (engl. cycle) on polku (v 0,v 1,...,v k ) missä k 3 ja v 0 = v k Sykli (v 0,v 1,...,v k ) on yksinkertainen jos v 1,v 2,...,v k ovat erillisiä Verkko on syklitön (engl. acyclic) jos siinä ei ole yhtään yksinkertaista sykliä Esimerkki: Vasemmanpuoleinen verkko ei ole syklitön koska se sisältää yksinkertaisen syklin (a,e,f,a) Oikeanpuoleinen verkko on syklitön e c g e c g a d a d f b f b 10/61

Puut ja metsät Juureton puu on yhtenäinen syklitön suuntaamaton verkko Puhutaan vain puista jos juurettomuus on selvää asiayhteydestä Suuntaamaton verkko, joka on syklitön muttei välttämättä yhtenäinen on metsä Esimerkki: Vasemmanpuoleinen verkko on puu Oikeanpuoleinen verkko on kahdesta puusta koostuva metsä e c g e c g a d a d f b f b 11/61

Teoreema B.2 kirjassa Introduction to Algorithms, 3rd ed. (online via Aalto lib) Jos G = (V, E) on suuntaamaton verkko, niin seuraavat lauseet ovat yhtäpäteviä: G on juureton puu Jokainen solmupari verkossa G on yhdistetty yhdellä yksinkertaisella polulla G on yhtenäinen mutta minkä tahansa kaaren poistaminen tekee siitä epäyhtenäisen G on yhtenäinen ja E = V 1 G on syklitön ja E = V 1 G on syklitön mutta minkä tahansa kaaren lisääminen siihen saa aikaan syklin 12/61

Juurelliset puut Juurellinen puu on kuten juureton puu mutta yksi solmuista on puun juuri Esimerkki: Alla oleva kuva esittää juurellisen version aiemman esimerkin juurettomasta puusta kun juurena toimii solmu c. Puita piirrettäessä juurisolmu piirretään aina samaan kohtaan, yleensä ylimmäiseksi solmuksi. c d g a b e f Kuten aiemminkin, jos puiden juurellisuus on selvää asiayhteydestä, niin puhutaan vain puista 13/61

Tarkastellaan juurellista puuta, jonka juurisolmu on r Solmu y, joka on ainoalla yksinkertaisella polulla juuresta r johonkin solmuun x on solmun x edeltäjä Jos y on solmun x edeltäjä, niin x on solmun y jälkeläinen Jos y on solmun x edeltäjä ja x y, niin y on solmun x aito edeltäjä ja x on solmun y aito jälkeläinen Jos y on solmun x edeltäjä ja {y,x} on kaari, niin y on solmun x ainoa vanhempi ja x on solmun y lapsi Jos kahdella solmulla on sama vanhempi, niin ne ovat sisaruksia Juurella ei ole vanhempaa ja lapsettomat solmut ovat lehtiä Lehtisolmuja sanotaan myös uloimmaisiksi solmuiksi ja muita solmuja sisäsolmuiksi Esimerkki: Oikealla olevassa puussa solmun e edeltäjät ovat e, a ja c solmun a jälkeläiset ovat a, b, e ja f solmun a vanhempi on c ja sen lapset ovat b ja e lehtisolmut ovat d, g, b ja f c d g a b e f 14/61

Solmun x alipuu on solmun x jälkeläisistä koostuva aliverkko Solmun x syvyys (engl. depth) on juuresta siihen tulevan yksinkertaisen polun pituus Puun taso (engl. level) koostuu kaikista niistä solmuista, joilla on jokin sama syvyys Solmun x korkeus (engl. height) on pisimmän yksinkertaisen polun pituus siitä johonkin lehtisolmuun Puun korkeus on sen juurisolmun korkeus Puun solmun asteluku on sen lasten lukumäärä Esimerkki: Oikeanpuoleisessa puussa solmun a alipuu koostuu solmuista a, b, e ja f solmun b syvyys on 2 solmut tasolla 1 ovat d, g ja a c d g a b e solmun a korkeus on 2 ja asteluku 2 f koko puun korkeus on 3 15/61

Järjestetty puu on juurellinen puu, jonka jokaisen solmun lapsilla on jokin järjestys Eli jos solmulla on k lasta, niin yksi niistä on ensimmäinen lapsi, yksi on toinen lapsi, jne Esimerkki: Alla olevat juurelliset puut ovat samoja jos ne tulkitaan ei-järjestetyiksi kuten aiemmin mutta erilaisia jos ne tulkitaan järjestetyiksi c c d g a g a d b e e b f f Vasemmanpuoleisessa puussa solmun c ensimmäinen lapsi on d, toinen g ja kolmas a 16/61

Binääripuut Binääripuut ovat järjestettyjen puiden eräs yleinen aliluokka, missä jokaisella solmulla on enintään kaksi lasta, vasen ja oikea lapsi, ja jompikumpi tai kumpikin näistä voi puuttua Tämä on eri asia kuin korkeintaan asteluvun 2 järjestetty puu koska jos solmulla on vain yksi lapsi, binääripuussa sen täytyy olla joko vasen tai oikea lapsi Esimerkki: Alla olevat puut ovat binääripuita (vasen lapsi piirretään vanhempansa vasemmalle puolelle, oikea oikealle) Ne ovat eri binääripuita mutta samoja jos ne tulkitaan vain järjestetyiksi puiksi c c d a d a b e b e f f 17/61

Binääripuu on täysi (engl. full) jos jokainen solmu on joko lehti tai sisäsolmu, jolla on kaksi lasta. Binääripuu on täydellinen (engl. complete) jos kaikki lehdet ovat samalla syvyydellä Esimerkki: Vasen puu ei ole täysi eikä täydellinen Keskimmäinen puu on täysi muttei täydellinen Oikea puu on täydellinen c c c d a d a d a b e b e i m b e f g f k l n o h j g f 18/61

Täydellinen binääripuu, jonka korkeus on h, sisältää 2 h lehteä ja 2 h 1 sisäsolmua Harjoitus: todista ylläoleva väite induktiolla puun korkeuden suhteen Täydellisen binääripuun, jossa on n lehteä, korkeus on log 2 n 19/61

Tietorakenteita puiden esittämiseen Eri puutyyppejä voidaan esittää erilaisilla tietorakenteilla Eri puualgoritmit tarvitsevat erilaista tietoa, esimerkiksi jotkut algoritmit käyvät puita läpi juuresta lähtien ja ne tarvitsevat siten tietoa solmujen lapsista mutta jotkut algoritmit tarvitsevat vain tiedon solmun vanhemmasta Täten ei ole universaalisti parasta puiden esitysmuotoa 20/61

Yleinen tapa esittää binääripuita on esittää solmut olioina jokainen solmuolio sisältää viittauksen vanhempaan (jos solmu on juuri, tämä on joko null tai solmu itse) vasempaan ja oikeaan lapseen (null jos puuttuu) avaimeen/arvoon/alkioon/tms koska puita käytetään usein muun tiedon tallentamiseen Esimerkki: key parent left child right child Käytetään esitystä solmuille. Vasemmanpuoleisen puun oliodiagrammi on esitetty oikealla. Tässä ei olla kiinnostuttu solmujen nimistä ja täten nimien sijaan solmuihin liitetty arvo on piirretty myös vasemmanpuoleisessa puussa solmujen sisään 12 12 21 100 21 100 98-4 9 98-4 9 21/61

Juurellisia puita, joissa solmuilla voi olla mielivaltainen määrä lapsia voidaan esittää solmuolioilla, joista on viittaus ensimmäiseen omaan lapseen ja seuraavaan sisarukseen Esimerkki: key parent Käyttäen esitystä first child next sibling solmuolioille, vasemmanpuoleiselle puulle saadaan oikealla esitetty oliodiagrammi. 12 12 21 100 121 21 100 121 98-4 9 98-4 9 Jos solmulla on n lasta, tällä tavalla esitettynä i:n lapsen löytäminen vaatii pahimmillaan ajan Θ(n) kun i = n mutta lasten läpikäynti yksi kerrallaan on helppoa 22/61

Puiden läpikäynti Juurellisten puiden läpikäynti on tarpeen monessa algoritmissa Tähän on monta eri tapaa rippuen siitä, missä järjestyksessä solmut käsitellään: Esijärjestyksessä (engl. preorder) käsitellään ensin kyseinen solmu ja sen jälkeen lapset yksi kerrallaan Sisäjärjestyksessä (engl. inorder), erityisesti binääripuilla, käsitellään ensin vasen lapsi, sitten solmu itse ja lopuksi oikea lapsi Jälkijärjestyksessä (engl. postorder) käsitellään ensin lapset yksi kerrallaan ja sitten solmu itse Tasojärjestyksessä (engl. level order) käsitellään solmut tasoittain alkaen juuresta (harvinaisempi) traverse-preorder(tree T): def traverse(n): visit(n) for each child c of n: traverse(c) traverse(t.root) traverse-inorder(tree T): def traverse(n): traverse(n.leftchild) visit(n) traverse(n.rightchild) traverse(t.root) 23/61

traverse-postorder(tree T): def traverse(n): for each child c of n: traverse(c) visit(n) traverse(t.root) Esimerkki: Vasemmalla olevan binääripuun läpikäynti: Esijärjestyksessä: c,d,e,g,f,a,b,h Sisäjärjestyksessä: g,e,f,d,c,b,a,h Jälkijärjestyksessä: g,f,e,d,b,h,a,c Tasojärjestyksessä: c,d,a,e,b,h,g,f traverse-levelorder(tree T): level new Queue level.enqueue(t.root) while level is non-empty: nextlevel new Queue while level is non-empty: n level.dequeue() visit(n) for each child c of n: nextlevel.enqueue(c) level nextlevel g e d f c b a h 24/61

Läpikäynti ei ole aina niin puhdasoppista kuin pseudokoodissa Esimerkki: Aritmeettisten lausekkeiden tulostaminen prefix-, infix- ja postfixesitysmuodoissa abstract class Expr { def p r e f i x S t r : S t r i n g def i n f i x S t r : S t r i n g def p o s t f i x S t r : S t r i n g } case class Negate ( expr : Expr ) extends Expr { def p r e f i x S t r : S t r i n g = " Negate ( " +expr. p r e f i x S t r + " ) " def i n f i x S t r : S t r i n g = " " +expr. i n f i x S t r def p o s t f i x S t r : S t r i n g = expr. p o s t f i x S t r + " " } case class Add ( l e f t : Expr, r i g h t : Expr ) extends Expr { def p r e f i x S t r : S t r i n g = " Add ( " + l e f t. p r e f i x S t r + ", " + r i g h t. p r e f i x S t r + " ) " def i n f i x S t r : S t r i n g = " ( " + l e f t. i n f i x S t r + " + " + r i g h t. i n f i x S t r + " ) " def p o s t f i x S t r : S t r i n g = l e f t. p o s t f i x S t r + " " + r i g h t. p o s t f i x S t r + " + " }... case class Num( value : Double ) extends Expr { def p r e f i x S t r : S t r i n g = "Num( " +value. t o S t r i n g + " ) " def i n f i x S t r : S t r i n g = value. t o S t r i n g def p o s t f i x S t r : S t r i n g = value. t o S t r i n g } 25/61

Lauseketta (2.0x + y) vastaava puu saadaan komennolla val e = Negate(Add(Multiply(Num(2.0),Var("x")),Var("y"))) e.prefixstr tuottaa Negate(Add(Multiply(Num(2.0),Var("x")),Var("y"))) e.infixstr tuottaa -((2.0*x)+y) e.postfixstr tuottaa 2.0 x * y + - Postfix-muodossa ei tarvita sulkeita ja se voidaan lukea ja evaluoida tekstimuodosta helposti käyttämällä pinoa (ks. esim. tämä artikkeli) Num value = 2.0 Multiply left right Negate expr Add left right Var name = "x" Var name = "y" 26/61

Keot 27/61

Kekotietorakennetta (engl. heap) voidaan käyttää toteuttamaan prioriteettijonoja ja järjestämiseen (kekojärjestäminen) Abstraktilla tasolla prioriteettijono on säiliötietorakenne, joka tukee alkioiden, joilla on prioriteettiavain, lisäämistä suurimman avaimen omaavan alkion etsimistä, ja suurimman avaimen omaavan alkion poistamista. (Oltaisiin voitu tehdä sama määrittely myös pienimmälle avaimelle.) Usealla alkiolla voi olla sama avain Täten prioriteettijono on abstrakti tietotyyppi, jonka rajapinta voisi olla INSERT(x) lisää alkion x avaimella x.key jonoon MAX() palauttaa jonon alkion, jolla on suurin avain REMOVE-MAX() poistaa jonosta alkion, jolla on suurin avain INCREASE-KEY(x, v) kasvattaa alkion x avaimen arvoa arvoon v DECREASE-KEY(x, v) pienentää alkion x avaimen arvoa arvoon v 28/61

Prioriteettijonojen käyttökohteita voisivat olla esim. avointen tilausten priorisointi asiakastyypin mukaan, verkkoliikennepakettien priorisointi yhteystyypin tai aiemman käyttöasteen mukaan, saapuvien tapahtumien suorittaminen aikajärjestyksessä simulaatio-ohjelmistossa, ja parhaan seuraavan alkion valinta toisissa algoritmeissa (Dijkstran algoritmi myöhemmin tällä kurssilla jne) Huomionarvoista on, että alkioita lisätään ja poistetaan jonoon koko ajan (engl. online) eli kaikkia alkioita ei välttämättä alussa tiedetä eikä niitä voida siten vain järjestää kertaalleen Voitaisiin käyttää dynaamisia taulukoita ja sitten jotain ajassa O(nlog 2 n) toimivaa järjestämisalgoritmia ennen jokaista etsi/poista suurin/pienen alkio -operaatiota mutta tahdotaan saada aikaan parempi algoritmi siten, että jokainen lisäys ja poisto on vie ajan O(log 2 n) jos jonossa on sillä hetkellä n alkiota 29/61

Keot ja keko-ominaisuudet Keko on melkein täydellinen binääripuu, missä kaikki tasot ovat täysiä paitsi mahdollisesti viimeinen, joka sekin on täynnä vasemmalta oikealle johonkin solmuun asti jokaiseen solmuun on liitetty alkio ja alkioilla on keskenään vertailtavissa oleva avain (kokonaisluku tms) jompikumpi keko-ominaisuus pätee: jokaisen solmun avain on vähintään yhtä suuri kuin kummankin sen lapsen avain (tällöin kyseessä on maksimikeko), tai jokaisen solmun avain on korkeintaan yhtä suuri kuin kummankin sen lapsen avain (tällöin kyseessä on minimikeko) Suorana seurauksena saadaan, että n-solmuisen keon korkeus on log2 n Ei-tyhjässä maksimikeossa juurisolmu sisältää (erään) alkion, jolla on suurin avain Ei-tyhjässä minimikeossa juurisolmu sisältää (erään) alkion, jolla on pienin avain 30/61

Esimerkki: Kolme melkein täydellistä binääripuuta; solmuihin liitettyjen alkioden avaimet on kuvattu solmujen sisällä solmun nimen sijaan 35 17 17 28 34 28 20 16 20 28 20 28 35 34 28 35 34 Maksimikeko Minimikeko Puu, joka ei ole keko 31/61

Kekojen esittäminen muistissa Kekoja ei yleensä tallenneta muistiin solmuina, joista on viittauksia lapsisolmuihin jne Sen sijaan käytetään hyväksi sitä, että keot ovat melkein täydellisiä binääripuita ne voidaan esittää hyvin tiiviisti taulukoiden avulla Idea: n-solmuinen keko esitetään taulukkona, jossa on n alkiota Solmut numeroidaan välille 0,..., n 1 tasoittain, jokainen taso vasemmalta oikealle Solmun i alkio talletetaan taulukon alkioon a[i] Solmun i vasen lapsi on solmu 2i + 1 Jos 2i + 1 n, niin solmulla i ei ole vasenta lasta Solmun i oikea lapsi on solmu 2i + 2 Jos 2i + 2 n, niin solmulla i ei ole oikeaa lasta Solmun i, joka ei ole juuri, vanhempi on solmu parent(i) = i 1 2 32/61

Esimerkki: Edellisen esimerkin maksimi- ja minimikeot puina, kunkin solmun numero näkyvillä solmun vieressä, ja taulukoina 0 0 35 17 1 28 2 34 1 28 2 20 3 4 3 4 5 28 20 28 35 34 0 1 2 3 4 35 28 34 28 20 0 1 2 3 4 5 17 28 20 28 35 34 33/61

Kekojen rakentaminen Tarkastellaan jatkossa vain maksimikekoja minimikekojen käsittely samantapaista Monissa keko-operaatioissa, kuten alkioiden lisäämisessä, 1. aloitetaan kunnossa olevasta maksikeosta, 2. tehdään pieni paikallinen muutos, kuten alkion lisäys, ja 3. jos maksimikeko-ominaisuus ei enää päde, tehdään sarja muunnoksia, joiden jälkeen se jälleen pätee Ennen varsinaisten keko-rajapinnan operaatioiden kuvaamista esitetään kaksi apumenetelmää, joita käyttämällä rikki mennyt keko-ominaisuus saadaan korjattua (kolmas askel yllä) 34/61

upheap tai swim Nimellä Heap-Increase-Key kirjassa Introduction to Algorithms, 3rd ed. (online via Aalto lib) Oletetaan, että solmun i avaimen arvoa kasvatetaan Maksimikeko-ominaisuus voi nyt olla rikki jos avaimesta tuli suurempi kuin sen vanhemman parent(i) avaimesta Tällöin vaihdetaan solmujen i ja parent(i) alkiot Maksimikeko-ominaisuus pätee nyt alipuussa, jonka juuri on solmu i koska solmun parent(i) avain oli suurempi kuin solmun i ennen avaimen arvon kasvattamista alipuussa, jonka juuri on solmu parent(i) koska solmun parent(i) uusi avain on suurempi kuin sen entinen avain Mutta maksimikeko-ominaisuus voi nyt olla rikki jos solmun parent(i) uusi avain on suurempi kuin sen vanhemman avain toistetaan korjausprosessia kunnes maksimikeko-ominaisuus pätee koko puussa Jokaisella askeleella yllä tehdään vakiomäärä operaatioita Prosessi toistuu korkeintaan O(log 2 n) kertaa koska se pysähtyy viimeistään juurisolmussa 35/61

Esimerkki: Solmun avaimen kasvattaminen ja upheap-menetelmän käyttäminen maksimikeko-ominaisuuden palauttamiseksi 0 0 0 0 35 35 35 40 1 2 1 2 1 2 1 2 29 34 29 34 40 34 35 34 3 4 3 4 3 4 3 4 28 20 28 40 28 29 28 29 0 1 2 3 4 35 29 34 28 20 0 1 2 3 4 35 29 34 28 40 0 1 2 3 4 35 40 34 28 29 0 1 2 3 4 40 35 34 28 29 Aloitus Kasvatetaan Vaihdetaan solmujen Vaihdetaan solmujen solmun 4 avainta 1 ja 4 alkiot 0 ja 1 alkiot 36/61

downheap aka sink Nimellä Max-Heapify kirjassa Introduction to Algorithms, 3rd ed. (online via Aalto lib) Oletetaan, että solmun i avaimen arvoa pienennetään Maksimikeko-ominaisuus voi tällöin mennä rikki jos uusi vain on pienempi kuin jommankumman tai kummankin lapsisolmun avain Tällöin vaihdetaan solmun i ja suuremman avaimen omistavan lapsen j alkiot solmun i avain on nyt vähintään yhtä suuri kuin toisenkin lapsen korkeintaan yhtä suuri kuin solmun parent(i) koska solmun i alkuperäinen avain oli vähintään yhtä suuri kuin solmun j avain Maksimikeko-ominaisuus voi nyt olla rikki koska solmun j uusi pienempi avain voi olla pienempi kuin jompikumpi sen lapsen avaimista toistetaan prosessia kunnes maksimikeko-ominaisuus pätee Jokaisella askeleella yllä tehdään vakiomäärä operaatioita Tehdään korkeitaan O(log 2 n) askelta koska prosessi päättyy viimeistään lehtisolmussa 37/61

Esimerkki: Avaimen pienentäminen ja maksimikeko-ominaisuuden palauttaminen downheap -menetelmällä 0 0 0 0 35 17 34 34 1 2 1 2 1 2 1 2 29 34 29 34 29 17 29 19 3 4 5 3 4 5 3 4 5 3 4 5 28 20 19 28 20 19 28 20 19 28 20 17 0 1 2 3 4 5 35 29 34 28 20 19 0 1 2 3 4 5 17 29 34 28 20 19 0 1 2 3 4 5 34 29 17 28 20 19 0 1 2 3 4 5 34 29 19 28 20 17 Aloitus Pienennetään Vaihdetaan solmujen Vaihdetaan solmujen solmun 0 avainta 1 ja 2 alkiot 2 ja 5 alkiot 38/61

Maksimikeko-operaatiot: alkion lisääminen Käyttämällä upheap-menetelmää, alkioiden lisääminen on helppoa Esimerkki: 1. Kasvatetaan taulukon kokoa yhdellä ja lisätään alkio uuteen solmuun taulukon lopussa 2. Käytetään upheap-menetelmää uuteen solmuun maksimikeko-ominaisuuden aikaansaamiseksi Alkion, jonka avain on 42, lisääminen kekoon: 0 0 0 0 34 34 34 42 1 2 1 2 1 2 1 2 29 19 29 19 29 42 29 34 3 4 5 3 4 5 6 3 4 5 6 3 4 5 6 28 20 17 28 20 17 42 28 20 17 19 28 20 17 19 0 1 2 3 4 5 34 29 19 28 20 17 0 1 2 3 4 5 6 34 29 19 28 20 17 42 0 1 2 3 4 5 6 34 29 42 28 20 17 19 Aloitus Lisätään uusi Upheap Upheap solmu loppuun 0 1 2 3 4 5 6 42 29 34 28 20 17 19 39/61

Maksimikeko-operaatiot: maksimialkion löytäminen ja poistaminen Alkio (ei välttämättä ainoa), jolla on suurin avain, on taulukon alussa Sen poistaminen keosta voidaan tehdä downheap-menetelmällä 1. Siirretään viimeinen solmu taulukon lopusta taulukon ensimmäiseen kohtaan (sen avaimen arvo on korkeintaan sama kuin poistuvan solmun) 2. Pienennetään taulukon kokoa yhdellä 3. Käytetään downheap-menetelmää juurisolmuun maksimikeko-ominaisuuden palauttamiseksi Esimerkki: Suurimman avaimen sisältävän alkion poistaminen: 0 0 0 0 34 17 29 29 1 2 1 2 1 2 1 2 29 19 29 19 17 19 28 19 3 4 5 3 4 3 4 3 4 28 20 17 28 20 28 20 17 20 0 1 2 3 4 5 34 29 19 28 20 17 0 1 2 3 4 17 29 19 28 20 0 1 2 3 4 29 17 19 28 20 Aloitus Siirretään viimeinen Downheap Downheap 0 1 2 3 4 29 28 19 17 20 40/61

Toteutuksia standardikirjastoissa java.util.priorityqueue toteuttaa prioriteettijonot minimikeoilla Alkioiden lisääminen ja pienimmän poisto ajassa O(log 2 n) Mielivaltaisen alkion etsintä ja poisto ajassa O(n) PriorityQueue Scala-kielessä käyttää maksimikekoja Alkioiden lisääminen ja suurimman poisto ajassa O(log 2 n) Mielivaltaisen alkion etsintä ja poistaminen ja muita operaatioita ajassa O(n) C++ priority_queue käyttää maksimikekoja Alkioiden lisääminen ja suurimman poisto ajassa O(log 2 n) Ei tukea mielivaltaisten alkioiden etsimiselle jne Mielenkiintoista sinänsä, etteivät yllä mainitut tue kasvata alkion avainta tai pienennä alkion avainta operaatioita 41/61

Erilliset joukot eli yhdistä-ja-etsi 42/61

Toinen esimerkki puiden käyttämisestä tietorakenteena on erillisten joukkojen esittäminen Tällainen erillisten joukkojen tietorakenne (engl. disjoint sets data structure, union-find data structure) pitää yllä jonkin alkiojoukon S jakoa pistevieraisiin osajoukkoihin S 1,...,S k eli S 1... S k = S ja S i S j = /0 kaikille 1 i < j k. Alussa jokainen alkio a on omassa joukossaan {a} Kaksi alkiota, x ja y, sisältävät joukot S x ja S y voidaan yhdistää yhdeksi joukoksi S x S y Jokaiselle joukolle on määritelty edustaja-alkio, ja joukon alkioille saadaan selville tämä alkio voidaan tarkastaa ovatko kaksi alkiota samassa joukossa tarkastamalla, ovatko niiden edustaja-alkiot samat 43/61

Abstrakti tietotyyppi Erillisten joukkojen abstraktilla tietotyyppillä on seuraava rajapinta ja toiminnalisuus: MAKE-SET(x) esittelee uuden alkion x ja laittaa sen omaan yksikköjoukkoonsa {x} FIND-SET(x) etsii alkion x sisältävän joukon nykyisen edustaja-alkion Kaksi alkiota, x ja y, ovat samassa joukossa jos ja vain jos niiden edustaja-alkiot (engl. representative) ovat samat eli FIND-SET(x) = FIND-SET(y) UNION(x, y) yhdistää alkiot x ja y sisältävät joukot yhdeksi. Uuden joukon kaikkien alkioiden edustaja-alkio voi tällöin muuttua. 44/61

Esimerkki: Suuntaamattoman verkon yhtenäisyyden tarkastaminen Tarkastellaan oikealla olevaa verkkoa. Alustetaan erillisten joukkojen tietorakenne kutsumalla MAKE-SET(x) jokaiselle x {a,b,c,d,e,f,g} Erilliset joukot ovat nyt {a},{b},{c},{d},{e},{f },{g} Kutsutaan UNION(x, y) jokaiselle verkon kaarelle {x, y} e f a c b g d Jokaisen kutsun jälkeen kaksi solmua x ja y ovat samassa joukossa jos jo käsiteltyjen kaarten avulla päästään solmusta x solmuun y Erilliset joukot ovat lopussa {a,b,e,f } ja {c,d,g} Koska erillisiä joukkoja on 2 kappaletta, verkko ei ole yhtenäinen Kaksi solmua x ja y kuuluvat samaan yhtenäiseen komponenttiin jos FIND-SET(x) = FIND-SET(y) 45/61

Yhdistä-ja-etsi erillisten joukkojen metsillä Juurellisista puista koostuvat metsät mahdollistavat erillisten joukkojen tehokkaan esittämisen Jokainen joukko on esitetty puuna siten, että puiden solmuihin on liitetty joukossa esiintyvät alkiot Jokaisen puun juuri on ko. joukon edustaja-alkio Operaatiot toteuttavat algoritmit käyvät puita läpi vain lehdistä juureen päin viittauksia lapsisolmuihin ei tarvita, vain vanhempaan Esimerkki: Olkoon esiteltyinä alkiot a, b,..., f ja sitten yhdistetty joukkoja niin, että nykyiset joukot ovat {a,c,d,e} ja {b,f }. Oikealla on eräs mahdollinen esitys näille joukoille Joukkojen edustaja-alkiot ovat nyt e ja f a e d c f b 46/61

Operaatiot: Alkioiden esittely eli MAKE-SET(x) Uusien alkioiden esittely omaksi yksikköjoukokseen on helppoa, lisätään metsään vain uusi ko. alkion sisältävä solmu, joka ei ole kytköksissä mihinkään aiempaan solmuun Pseudokoodina // Insert the element x as a singleton set if not already in any set MAKE-SET(x): if x is not yet in any set: insert x in some data structure recording the elements in the sets x.parent NIL // as a field or with a map Kuten aiemmin mainittiin, puita käydään läpi vain vanhempiin joten viittauksia lapsisolmuihin ei tarvita Rivin kaksi tarkistus voidaan tehdä jollakin hakurakenteella (hajautustaulu eli Scalan HashSet tms), joiden toteutusta tarkastellaan seuraavilla kierroksilla Samoin x.parent tarkoittaa, että alkioon x liitetään jollain tapaa tieto sen vanhemmasta; helpoiten ehkäpä assosiatiivisen taulukon (Scalan HashMap tms) avulla, jolloin alkioon ei tarvitse lisätä uusia kenttiä 47/61

Operaatiot: Edustaja-alkion etsiminen eli FIND-SET(x) Alkion x sisältävän joukon edustaja-alkion löytäminen on myös helppoa: etsitään alkion sisältävä solmu metsistä ja seurataan viittauksia vanhempiin kunnes tullaan ko. joukkoa esittävän puun juureen Pseudokoodina // Find the representative of the set containing x FIND-SET(x): raise an error if x is not in any set while x.parent NIL: x x.parent return x 48/61

Operaatiot: Joukkojen yhdistäminen eli UNION(x, y) Alkiot x ja y sisältävien joukkojen yhdistäminen on myös melko suoraviivaista: Ensin etsitään alkiot sisältävien puiden juurisolmut edellä kuvatulla tavalla Jos juuret eivät ole sama solmu eli alkiot eivät ole vielä samassa joukossa, yhdistetään puut laittamalla toinen juurisolmu olemaan toisen lapsi Pseudokoodina UNION(x, y): Check that y and y are in some set x FIND-SET(x) // Find the root of the tree with x y FIND-SET(y) // Find the root of the tree with y if x y : // Not yet in the same set? x.parent = y // Merge the trees by making x a subtree of y 49/61

Esimerkki: Alkioiden lisääminen ja joukkojen yhdistäminen b c d e f b d e f a b c d e f MAKE-SET()-metodi kutsuttu kutsuttu alkioille a,..., f UNION(a, d) UNION(a, c) a a c f e f b e d e f d b d a c b a c kutsuttu kutsuttu kutsuttu UNION(b, f ) UNION(c, e) UNION(d, b) a c 50/61

Valitettavasti yllä esitetyt perusversiot operaatioiden toteutuksesta eivät ole riittäviä halutun suorituskyvyn saavuttamiseksi Pahimmassa tapauksessa puut degeneroituvat lineaarisiksi puiksi, jotka muistuttavat linkitettyjä listoja tällöin sekä etsi- että yhdistä-operaatiot vievät lineaarisen ajan Esimerkki: Pahimman tapauksen puut Jos tehdään operaatiot UNION(a, b), UNION(a, c), UNION(a, d), UNION(a, e) ja UNION(a, f ), tuloksena on lineaarinen puu. f e d c b a b c d e f (a) alussa a (b) lopussa 51/61

Tasapainottaminen Edellisen esimerkin puun ongelmana on, ettei se ole kovinkaan tasapainoinen Jos voidaan jotenkin pakottaa puut (edes suurinpiirtein) tasapainoisiksi niin, että lehtiä lukuunottamatta lapsia on vähintään kaksi ja lapsien alipuut ovat suurinpiirtein samankokoisia, puun korkeudeksi tulee O(log 2 n) ja tällöin etsija yhdistä-operaatiot ovat myös logaritmisen ajan operaatioita Onneksi tasapainoisuuden saavuttaminen on melko helppoa tässä yhteydessä: Jokaiseen solmuun liitetään rankki (engl. rank), joka kertoo solmun alipuun korkeuden Kun yhdistetään kaksi joukkoa, pienemmän korkeuden omaava alipuu liitetään toisen alipuuksi (saman korkeuden puut yhdistetään jomminkummin päin) 52/61

Päivitetty pseudokoodi: // Insert the element x as a singleton set if not already in any set MAKE-SET(x): if x is not yet in any set: insert x in some data structure recording the elements in the sets x.parent NIL // as a field or with a map x.rank 0 // as a field or with a map UNION(x, y): Check that y and y are in some set x FIND-SET(x) // Find the root of the tree with x y FIND-SET(y) // Find the root of the tree with y if x y : // Not yet in the same set? if x.rank < y.rank: // Subtree at x has less height? x.parent y // Merge the trees by making x a subtree of y else: y.parent x // Merge the trees by making y a subtree of x if x.rank = y.rank: x.rank x.rank + 1 53/61

Esimerkki: Aiempi esimerkki päivitetyllä koodilla, rankit on annettu solmujen vierellä: a 0 b 0 c 0 d 0 e 0 f 0 b 0 c 0 d 1 e 0 f 0 b 0 d 1 e 0 f 0 a 0 alussa UNION(a, d) UNION(a, c) a 0 c 0 f 2 d 1 e 0 f 1 d 1 f 1 b 0 d 1 a 0 c 0 b 0 a 0 c 0 e 0 b 0 a 0 c 0 e 0 UNION(b, f ) UNION(c, e) UNION(d, b) 54/61

Esimerkki: Aiempi pahimman tapauksen esimerkki tasapainotuksella. Operaatioiden UNION(a,b), UNION(a,c), UNION(a,d), UNION(a,e) ja UNION(a,f ) tekeminen ei nyt saa aikaan lineaarista puuta vaan hyvin matalan puun. a 1 a 0 b 0 c 0 d 0 e 0 f 0 (a) alussa b 0 c 0 d 0 e 0 f 0 (b) lopussa 55/61

Teoreema Rankkeihin pohjautuvalla tasapainotuksella metsän jokaisen puun korkeus on korkeintaan log 2 s, missä s on kyseisen puun solmujen määrä. Todistus Induktiolla tehtyjen operaatioiden määrän suhteen. Perustapaus: 0 tehdyn operaation jälkeen väite pätee koska metsässä ei ole puita. Induktiohypoteesi: oletetaan, että väite pätee m tehdyn operaation jälkeen. Induktioaskel: Jos seuraava operaatio on etsi, metsä ei muutu ja väite pätee m + 1 tehdyn operaation jälkeen. Jos lisätään uusi alkio, (i) lisätään uusi yksinäinen puu, jossa on 1 solmu ja jonka korkeus on 0 = log 2 1 ja (ii) muut puut eivät muutu. Koska minkä tahansa toisen puun korkeus oli korkeintaan log 2 s hypoteesin mukaan, sen korkeus on korkeintaan log 2 (s + 1) lisäyksen jälkeen. 56/61

Yhdistettäessä alkiot x ja y sisältävät joukot tarkastellaan kahta eri tapausta. 1. Jos alkiot ovat jo samassa joukossa, puut pysyvät muuttumattomina. 2. Jos alkiot ovat eri joukoissa, joiden koot ovat s x ja s y, niin vastaavien puiden korkeudet ovat hypoteesin mukaan h x log 2 s x ja h y log 2 s y. Jos h x < h y, niin uusi puu sisältää s x + s y solmua ja sen korkeus on h y. Koska h y log 2 s y, niin h y log 2 (s x + s y ). Tapaus h y < h x on symmetrinen edellisen kanssa. Jos h x = h y, niin uusi puu sisältää s = s x + s y solmua ja sen korkeus on h = h x + 1 = h y + 1. Jos s x s y, niin s 2s x ja log 2 (s ) log 2 (2s x ) = log 2 (2) + log 2 s x = 1+ log 2 s x = h. Vastaavasti jos s x s y, niin s 2s y ja log 2 (s ) log 2 (2s y ) = log 2 (2) + log 2 s y = 1+ log 2 s y = h. Täten väite pätee m + 1 tehdyn operaation jälkeen ja siten induktioperiaatteen mukaisesti kaikille arvoille m. 57/61

Olkoon n kulloisissa joukoissa esiintyvien alkioiden lukumäärä Oletetaan, että voidaan 1. löytää alkion sisältävä solmu ajassa O(log 2 n) 2. lukea ja päivittää solmun viittaus vanhempaan ja rankki-arvoon vakioajassa Seuraus Rankkeihin pohjautuvalla tasapainottamisella alkioiden lisääminen, edustaja-alkion etsiminen ja joukkojen yhdistäminen voidaan tehdä ajassa O(log 2 n). 58/61

Polkujen tiivistäminen Toinen idea, jolla voidaan saada syntyvät puut vieläkin matalammiksi, on tiivistää polkuja solmuista juureen päin etsi-operaatioiden yhteydessä Tehdään haku juureen päin rekursiivisesti, palautetaan löydetty juurisolmu kutsun lopuksi, ja päivitetään välisolmujen vanhempi osoittamaan suoraan juurisolmuun Pseudokoodina: // Find the representative of the set containing x FIND-SET(x): raise an error if x is not in any set def FIND-AND-COMPRESS(y): if y.parent = NIL: // In the root? return y else r FIND-AND-COMPRESS(y.PARENT) y.parent r return r return FIND-AND-COMPRESS(x) 59/61

Esimerkki: Taskastellaan vasemmalla näkyvää erillisten joukkojen metsää. Jos kutsutaan metodia FIND-SET(c), niin metsä muovautuu oikealla puolella esitetyksi. e f e f d b c d b a c a Huomaa, että etsi-operaatiota kutsutaan myös yhdistämis-operaation aikana, joten polkujen tiivistämistä tapahtuu myös tuolloin 60/61

Teoreema Jos käytetään sekä rankkeihin pohjautuvaa tasapainottamista että polkujen tiivistämistämistä, niin m operaation tekeminen n alkion joukoille vie ajan O(m α(m)), missä α on hyvin hitaasti kasvava funktio, jolle pätee α(m) 4 kaikille m 2 2048. Todistus Kappale 21.4 kirjassa Introduction to Algorithms, 3rd ed. (online via Aalto lib), ei kuulu kurssin sisältöön. 61/61