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

Samankaltaiset tiedostot
CS-A1140 Tietorakenteet ja algoritmit

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

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

CS-A1140 Tietorakenteet ja algoritmit

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ö

811312A Tietorakenteet ja algoritmit III Lajittelualgoritmeista

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

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)

1 Puu, Keko ja Prioriteettijono

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

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

Algoritmit 2. Luento 5 Ti Timo Männikkö

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

58131 Tietorakenteet Erilliskoe , ratkaisuja (Jyrki Kivinen)

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

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

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

Johdatus graafiteoriaan

811312A Tietorakenteet ja algoritmit, , Harjoitus 5, Ratkaisu

Fibonacci-kasoilla voidaan toteuttaa samat operaatiot kuin binomikasoilla.

Binäärihaun vertailujärjestys

Algoritmit 2. Demot Timo Männikkö

Algoritmit 2. Luento 3 Ti Timo Männikkö

Algoritmit 2. Luento 9 Ti Timo Männikkö

Algoritmit 1. Luento 6 Ke Timo Männikkö

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

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ö

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

10. Painotetut graafit

Algoritmit 1. Luento 5 Ti Timo Männikkö

58131 Tietorakenteet ja algoritmit Uusinta- ja erilliskoe malliratkaisut ja arvosteluperusteet

Tietorakenteet, laskuharjoitus 6,

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.

Pienin virittävä puu (minimum spanning tree)

B + -puut. Kerttu Pollari-Malmi

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

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

Tietorakenteet, laskuharjoitus 7, ratkaisuja

Tietorakenteet ja algoritmit - syksy

A TIETORAKENTEET JA ALGORITMIT

Kysymyksiä koko kurssista?

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

Tietorakenteet, laskuharjoitus 3, ratkaisuja

811312A Tietorakenteet ja algoritmit II Perustietorakenteet

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

(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 13 Ma Timo Männikkö

Algoritmit 1. Luento 12 Ti Timo Männikkö

811312A Tietorakenteet ja algoritmit, , Harjoitus 5, Ratkaisu

Algoritmit 1. Luento 12 Ke Timo Männikkö

3. Binääripuu, Java-toteutus

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

Johdatus graafiteoriaan

Luku 8. Aluekyselyt. 8.1 Summataulukko

Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari Korhonen

Ohjelmoinnin perusteet Y Python

Tarkennamme geneeristä painamiskorotusalgoritmia

1.1 Tavallinen binäärihakupuu

isomeerejä yhteensä yhdeksän kappaletta.

Algoritmit 2. Luento 14 Ke Timo Männikkö

Datatähti 2019 loppu

811312A Tietorakenteet ja algoritmit Kertausta jälkiosasta

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

7. Tasapainoitetut hakupuut

Algoritmit 2. Luento 10 To Timo Männikkö

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

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.

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

Transkriptio:

Kierros 3: Puut Tommi Junttila Aalto University School of Science Department of Computer Science CS-A1140 Data Structures and Algorithms Autumn 2017 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 1 / 62

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) Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 2 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 3 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 4 / 62

Puut Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 5 / 62

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" Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 6 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 7 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 8 / 62

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 e c g sisältää yksinkertaisen 2 askeleen polun (a, c, d) solmusta a solmuun d a d on yhtenäinen mutta kaaren {a, c} poistaminen tekisi siitä ei-yhtenäisen f b Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 9 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 10 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 11 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 12 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 13 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 14 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 15 / 62

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 solmun a korkeus on 2 ja asteluku 2 koko puun korkeus on 3 c d g a b e f Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 16 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 17 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 18 / 62 f

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 19 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 20 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 21 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 22 / 62

Juurellisia puita, joissa solmuilla voi olla mielivaltainen määrä lapsia voidaan esittää solmuolioilla, joista on viittaus Esimerkki ensimmäiseen omaan lapseen ja seuraavaan sisarukseen 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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 23 / 62

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) Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 24 / 62

traverse-postorder(tree T ): def traverse(n): for each child c of n: traverse(c) visit(n) traverse(t.root) 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 Esimerkki Vasemmalla olevan binääripuun läpikäynti: c 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 e d b a h Tasojärjestyksessä: c,d,a,e,b,h,g,f g f Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 25 / 62

Läpikäynti ei ole aina niin puhdasoppista kuin pseudokoodissa Aritmeettisten lausekkeiden tulostaminen prefix-, infix- ja postfix-esitysmuodoissa 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 } Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 26 / 62

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) Negate expr Add left right Multiply Var left name = "y" right Num value = 2.0 Var name = "x" Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 27 / 62

Keot Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 28 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 29 / 62

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(n log 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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 30 / 62

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 log 2 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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 31 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 32 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 33 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 34 / 62

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ä) Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 35 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 36 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 37 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 38 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 39 / 62

Maksimikeko-operaatiot: alkion lisääminen Käyttämällä upheap-menetelmää, alkioiden lisääminen on helppoa 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 Esimerkki 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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 40 / 62

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 0 1 2 3 4 29 28 19 17 20 Aloitus Siirretään viimeinen Downheap Downheap solmu ensimmäiseksi Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 41 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 42 / 62

Erilliset joukot eli yhdistä-ja-etsi Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 43 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 44 / 62

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. Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 45 / 62

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) Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 46 / 62

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 e d f b a c Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 47 / 62

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ä Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 48 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 49 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 50 / 62

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(c, a) 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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 51 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 52 / 62

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 etsi- ja 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) Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 53 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 54 / 62

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(c, a) 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) Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 55 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 56 / 62

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. Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 57 / 62

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. Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 58 / 62

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). Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 59 / 62

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) Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 60 / 62

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 Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 61 / 62

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. Tommi Junttila (Aalto University) Kierros 3 CS-A1140 / Autumn 2017 62 / 62