Programmeringsmetodik DV1 Programkonstruktion 1. Moment 8 Om abstrakta datatyper och binära sökträd

Relevanta dokument
Tabeller. Programkonstruktion. Moment 8 Om abstrakta datatyper och binära sökträd. Implementering av tabellen. Operationer på tabellen

Tabeller. Programkonstruktion. Moment 8 Om abstrakta datatyper och binära sökträd. Specifikationer för tabellfunktionerna. Operationer på tabellen

Programmeringsmetodik DV1 Programkonstruktion 1. Moment 9 Om högre ordningens funktioner. PK1&PM1 HT-06 moment 9 Sida 1 Uppdaterad

Tentamen (del 2) (4 högskolepoäng) i Programkonstruktion och datastrukturer (1DL201)

Programkonstruktion och datastrukturer. Moment 6 Om generella datastrukturer och träd. PKD 2012/13 moment 6 Sida 1 Uppdaterad

Datastrukturer. föreläsning 10. Maps 1

Programkonstruktion och. Datastrukturer

Träd Hierarkiska strukturer

Abstrakta datatyper. Primitiva vektorer. Deklarera en vektor

Ett generellt träd är. Antingen det tomma trädet, eller en rekursiv struktur: rot /. \ /... \ t1... tn

TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 14-18

Datastrukturer, algoritmer och programkonstruktion (DVA104, HT 2014) Föreläsning 5

Föreläsning 9 Innehåll

Föreläsning 7. Träd och binära sökträd

Föreläsning 9 Innehåll

Datastrukturer i kursen. Föreläsning 8 Innehåll. Träd rekursiv definition. Träd

Algoritmer och datastrukturer 2012, fo rela sning 8

Föreläsning Datastrukturer (DAT036)

Programkonstruktion. Tentamen,

Föreläsning 9 Datastrukturer (DAT037)

Linjärt minne. Sammanhängande minne är ej flexibelt. Effektivt

Föreläsning 5. Träd Binära träd Binärt sökträd som ADT Implementering av binärt sökträd Travestera binärt sökträd Sökning Insättning/borttagning

Föreläsning 7. Träd och binära sökträd

Inom datalogin brukar man använda träd för att beskriva vissa typer av problem. Om man begränsar sig till träd där varje nod förgrenar sig högst två

Övningsuppgifter #11, Programkonstruktion och datastrukturer

Träd. Rot. Förgrening. Löv

Två fall: q Tom sekvens: () q Sekvens av element: (a b c) ; (sum-rec '(2 4 6)) = 12. q Första elementet uppfyller vissa villkor: (2 a b c)

Programkonstruktion. Tentamen,

Programkonstruktion. Tentamen,

TDDC74 Programmering: Abstraktion och modellering Tentamen, onsdag 9 juni 2016, kl 14 18

Datastrukturer. Föreläsning 5. Maps 1

Inlämningsuppgiften. Föreläsning 9 Innehåll. Träd. Datastrukturer i kursen

Programmering i C++ EDAF30 Dynamiska datastrukturer. EDAF30 (Föreläsning 11) HT / 34

Datastrukturer. föreläsning 10. Maps 1

Innehåll. Föreläsning 12. Binärt sökträd. Binära sökträd. Flervägs sökträd. Balanserade binära sökträd. Sökträd Sökning. Sökning och Sökträd

Självbalanserande AVL-träd Weiss, avsnitt 4.4

BINÄRA TRÄD. (X = pekarvärdet NULL): struct int_bt_node *pivot, *ny; X X X 12 X X 12 X X -3 X X

TENTAMEN: Algoritmer och datastrukturer. Läs detta! Uppgifterna är inte avsiktligt ordnade efter svårighetsgrad.

Programmering i C++ EDA623 Dynamiska datastrukturer. EDA623 (Föreläsning 11) HT / 31

Binära sökträd. Seminarium 9 Binära sökträd Innehåll. Traversering av binära sökträd. Binära sökträd Definition. Exempel på vad du ska kunna

Datastrukturer, algoritmer och programkonstruktion (DVA104, VT 2015) Föreläsning 6

Självbalanserande träd AVL-träd. Koffman & Wolfgang kapitel 9, avsnitt 1 2

Tentamen Datastrukturer (DAT036/DAT037/DIT960)

Föreläsning Datastrukturer (DAT036)

Datastrukturer. föreläsning 9. Maps 1

Föreläsning 3 Datastrukturer (DAT037)

Tentamen, Algoritmer och datastrukturer

Trädstrukturer och grafer

Föreläsning 13. Träd

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 8 Erik Nilsson, Institutionen för Datavetenskap, LiU

DD1320 Tillämpad datalogi. Lösnings-skiss till tentamen

Sökning. Översikt. Binärt sökträd. Linjär sökning. Binär sökning. Sorterad array. Linjär sökning. Binär sökning Hashtabeller

Föreläsning 4 Datastrukturer (DAT037)

3. Toppkvinnor på hög Låt lådan och de två kvinnornas famnar utgöra stackarna L, K1 respektive K2. Från början finns alla kort i L.

Tentamen Datastrukturer (DAT036)

Tentamen Datastrukturer, DAT037 (DAT036)

Föreläsning Datastrukturer (DAT037)

Programmering II (ID1019) :00-17:00

Lösningar Datastrukturer TDA

Seminarium 13 Innehåll

Föreläsning Datastrukturer (DAT036)

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 9 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Lösningsförslag till tentamen Datastrukturer, DAT037,

Programkonstruktion och datastrukturer. Moment 9 Om högre ordningens funktioner. PKD 2010/11 moment 9 Sida 1 Uppdaterad

ADT Prioritetskö. Föreläsning 13 Innehåll. Prioritetskö vs FIFO-kö. Prioritetskö Exempel på användning. Prioritetsköer och heapar

Programmeringsmetodik DV1, Programkonstruktion del 1 Tentamen,

ADT Prioritetskö. Föreläsning 12 Innehåll. Prioritetskö. Interface för Prioritetskö. Prioritetsköer och heapar

Produktionsplanering. Programkonstruktion. Ett programutvecklingsexempel. Programutvecklingsprocessen. Exempel produktregister. 2.

TDDC74 Programmering: Abstraktion och modellering Tentamen, lördag 27 augusti 2016, kl 8 12

Lösningsförslag till exempeltenta 1

Föreläsning 10 Innehåll. Prioritetsköer och heapar. ADT Prioritetskö. Interface för Prioritetskö. Exempel på vad du ska kunna

Upplägg. Binära träd. Träd. Binära träd. Binära träd. Antal löv på ett träd. Binära träd (9) Binära sökträd (10.1)

Föreläsning 2. AVL-träd, Multi-Way -sökträd, B-träd TDDD71: DALG. Innehåll. Innehåll. 1 Binära sökträd

Föreläsning 4 Datastrukturer (DAT037)

Datastrukturer och algoritmer. Innehåll. Tabell. Tabell - exempel. Gränsyta till Tabell. Tabell. Modell. Hashtabell Relation, lexikon.

Kryptokorsordslösare Programmeringsmetodik DV (period 2) Inlämningsuppgift 1

Tillämpad Programmering (ID1218) :00-13:00

Programkonstruktion och datastrukturer. Moment 5 Om generella datastrukturer och träd. PKD 2011/12 moment 5 Sida 1 Uppdaterad

Träd, binära träd och sökträd. Koffman & Wolfgang kapitel 6, avsnitt 1 4

DAI2 (TIDAL) + I2 (TKIEK)

Föreläsning 5 Datastrukturer (DAT037)

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

if (n==null) { return null; } else { return new Node(n.data, copy(n.next));

Föreläsning 10 Innehåll

Sätt att skriva ut binärträd

TDDC74 Programmering, abstraktion och modellering DUGGA 2

Föreläsning 11 Innehåll. Diskutera. Binära sökträd Definition. Inordertraversering av binära sökträd

Lösningsförslag för tentamen i Datastrukturer (DAT036) från

Datastrukturer och algoritmer. Innehåll. Trie. Informell specifikation. Organisation av Trie. Föreläsning 13 Trie och Sökträd.

Symboliska konstanter const

Föreläsning 13 Innehåll

Föreläsning 10 Innehåll. Diskutera. Inordertraversering av binära sökträd. Binära sökträd Definition

Föreläsning 3 Datastrukturer (DAT037)

Träd - C&P kap. 10 speciellt binära sökträd sid. 452

Det är principer och idéer som är viktiga. Skriv så att du övertygar rättaren om att du har förstått dessa även om detaljer kan vara felaktiga.

Innehåll. F7: Tabell, hashtabell, relation & lexikon. Gränsyta till Tabell. Tabell. Tabell Hashtabell Relation Lexikon.

TDDI16 Datastrukturer och algoritmer. Prioritetsköer, heapar, Union/Find

Försättsblad till skriftlig tentamen vid Linköpings Universitet

F5: Debriefing OU2, repetition av listor, träd och hashtabeller. Carl Nettelblad

Omtentamen (del 1, 6 högskolepoäng) i Programkonstruktion och datastrukturer (1DL201)

Transkript:

Programmeringsmetodik DV1 Programkonstruktion 1 Moment 8 Om abstrakta datatyper och binära sökträd PK1&PM1 HT-06 moment 8 Sida 1 Uppdaterad 2005-09-22

Tabeller En viktig tillämpning är tabellen att ifrån en nyckel kunna ta fram ett tabellvärde. Ett typiskt exempel är en telefonkatalog: Avdelningen för datalogi Andersson, Arne, professor i datalogi, 1022 Björklund, Henrik, doktorand, 1023 Bol, Roland, universitetslektor, 7606 Eriksson, Lars-Henrik, universitetslektor, 1057 Flener, Pierre, universitetslektor, 1028 Fomkin, Ruslan, doktorand, 1062 nyckel värde PK1&PM1 HT-06 moment 8 Sida 2 Uppdaterad 2005-09-22

Implementering av tabellen En tabell implementeras naturligen som en lista: val datalogi = [("Andersson, Arne",("professor i Datalogi",1022)), ("Björklund, Henrik",("doktorand",1023)), ("Bol, Roland",("universitetslektor",7606)), ("Eriksson, Lars-Henrik",("universitetslektor",1057)), ("Flener, Pierre",("universitetslektor",1028)), ("Fomkin, Ruslan",("doktorand",1062)),...] : (string * (string*int)) list; nyckeltyp värdetyp Listans typ blir alltså (nyckeltyp*värdetyp) list En invariant är att varje nyckel förekommer högst en gång. PK1&PM1 HT-06 moment 8 Sida 3 Uppdaterad 2005-09-22

Operationer på tabellen Skapa en tom tabell (empty) Lägg in en uppgift i tabellen (update) Hämta ett värde från tabellen (lookup) Tag bort en uppgift från tabellen (remove) Exempel: lookup("bol, Roland",datalogi) = SOME ("universitetslektor",7606) lookup("anka, Kalle",datalogi) = NONE PK1&PM1 HT-06 moment 8 Sida 4 Uppdaterad 2005-09-22

Tabellprogrammet lookup (* lookup(key,table) TYPE: ''a*(''a*'b) list -> 'b option PRE: table är en korrekt tabell. POST: SOME v om key finns i table och v är motsvarande värde. NONE annars. *) (* VARIANT: längden hos table *) fun lookup(_,[]) = NONE lookup(key,(key',value)::rest) = if key = key' then SOME value else lookup(key,rest); PK1&PM1 HT-06 moment 8 Sida 5 Uppdaterad 2005-09-22

Tabellprogrammet empty, update val empty = []; (* update(key,value,table) TYPE: ''a*'b*(''a*'b) list -> (''a*'b) list PRE: table är en korrekt tabell. POST: Tabellen table uppdaterad med värdet value för nyckeln key *) (* VARIANT: längden av table *) fun update(key, value, []) = [(key,value)] update(key, value, (key',value')::rest) = if key = key' then (key,value)::rest else (key',value')::update(key,value,rest); Observera att update respekterar datastrukturinvarianten att varje nyckel förekommer högst en gång i tabellen. PK1&PM1 HT-06 moment 8 Sida 6 Uppdaterad 2005-09-22

Tabellprogrammet remove (* remove(key,table) TYPE: ''a*(''a*'b) list -> (''a*'b) list PRE: table är en korrekt tabell. POST: Tabellen table med uppgiften om nyckeln key borttagen *) (* VARIANT: längden av table *) fun remove(key, []) = [] remove(key, (key',value)::rest) = if key = key' then rest else (key',value)::remove(key,rest); Observera att även remove respekterar datastrukturinvarianten. PK1&PM1 HT-06 moment 8 Sida 7 Uppdaterad 2005-09-22

Tabelltyper Observera att tabellfunktionerna alla blir polymorfa: empty: (''a*'b) list lookup : ''a*(''a*'b) list -> 'b option update : ''a*'b*(''a*'b) list -> (''a*'b) list remove : ''a*(''a*'b) list -> (''a*'b) list Anledningen är att programmet aldrig utför någon operation på nycklar eller värden (bara likhetsjämförelser på nycklar) och därför inte bryr sig om vilka typer dessa har. Tabellerna får alltså typer på formen (''a*'b) list. Exempeltabellen hade typen (string*(string*int)) list, vilket är en instans av den polymorfa tabelltypen ovan. PK1&PM1 HT-06 moment 8 Sida 8 Uppdaterad 2005-09-22

Tabellkomplexitet En tabell med n nycklar representeras av en lista med n element. För att slå i tabellen måste man i genomsnitt söka igenom halva listan dvs n/2 rekursiva anrop av lookup. En lista med en miljon nycklar kräver i genomsnitt 500 000 anrop av lookup för att göra en tabellslagning. Detta är inte bra i praktiken. Tidsåtgången för lookup är alltså proportionell mot antalet nycklar i tabellen. Komplexiteten hos lookup är O(n). Samma resonemang gäller update och remove. PK1&PM1 HT-06 moment 8 Sida 9 Uppdaterad 2005-09-22

Abstrakta datatyper Vid användningen av en tabell enligt ovan utförs alla uppgifter av de olika tabellfunktionerna. Ett program som använder tabeller behöver alltså inte känna till att en tabell är representerad som en lista. Vill man ha en annan representation av tabellen (t.ex. för snabbare åtkomst!) så behöver man inte ändra programmet som använder tabellen, bara tabellfunktionerna har samma funktionsspecifikation! Det är också lättare att se till att invarianten uppfylls eftersom bara tabellfunktionerna kan skapa/ändra tabeller. En datatyp med denna egenskap kallas för en abstrakt datatyp eftersom man har abstraherat bort hur datatypen representeras (listan i vårt fall) och bara ser på hur den används (funktionerna). PK1&PM1 HT-06 moment 8 Sida 10 Uppdaterad 2005-09-22

Stöd för dataabstraktion i ML abstype datatypdeklaration with deklarationer end; Konstruktorerna i datatypsdeklarationen blir osynliga och oåtkomliga utom mellan with och end. abstype (''a,'b) table = Table of (''a*'b) list with val empty = Table []; fun update(key,value,table table) =...; fun lookup(key,table table) =...; fun remove(key,table table) =...; end; empty, update etc. kallas för datatypens primitiver. PK1&PM1 HT-06 moment 8 Sida 11 Uppdaterad 2005-09-22

Man brukar skilja på Olika sorters primitiver Konstruktorer primitiver som konstruerar nya värden av den abstrakta datatypen (t.ex. update) Selektorer primitiver som hämtar delar av värden (t.ex. lookup) Predikat primitiver som gör tester eller jämförelser på värden. Gränserna mellan dessa är dock inte skarp. PK1&PM1 HT-06 moment 8 Sida 12 Uppdaterad 2005-09-22

Intern dokumentation av abstrakta datatyper Inte bara funktioner utan också datatyper behöver dokumenteras. Varje abstype skall förses med en kommentar liknande en funktionsspecifikation som har två delar: En beskrivning av hur data är representerat Datastrukturinvarianten Alla definitioner av värden som inte är funktioner skall också dokumenteras med Namn på värdet Värdets typ Beskrivning av vad värdet representerar PK1&PM1 HT-06 moment 8 Sida 13 Uppdaterad 2005-09-22

Datatypsspecifikationer abstype (''a,'b) table = Table of (''a*'b) list (* REPRESENTATION CONVENTION: En tabell representeras som en lista där elementen är tabellrader. Varje tabellrad representeras av en tupel (nyckel,tabellvärde) REPRESENTATION INVARIANT: Ingen nyckel får finnas i mer än en tabellrad *) with (* empty TYPE: (''a*'b) table VALUE: En tom tabell *) val empty = Table []; (* funktionsspec för update *) fun update(key,value,table) etc end; PK1&PM1 HT-06 moment 8 Sida 14 Uppdaterad 2005-09-22

Nackdelar med dataabstraktion Man kan bara göra sådant som är förutsett. Exempel: Om man vill veta om tabellen är tom, så går inte det! (En lösning kan vara att lägga till en primitiv som ger tillbaka all information i tabellen i ett bestämt format, t.ex. som en lista.) Man kan förlora prestanda i vissa fall. Exempel: Om man vet att en nyckel inte finns i tabellen så kan man lägga in en ny uppgift för nyckeln i konstant tid genom att skriva (x,y)::table i stället för update(x,y,table). Eftersom konstruktorerna för den abstrakta datatypen inte går att använda (annat än av primitiverna) så kan man inte använda dem i matchning, vilket kan ge mer svårlästa program. PK1&PM1 HT-06 moment 8 Sida 15 Uppdaterad 2005-09-22

Likhetstyper Abstrakta datatyper i ML är inte likhetstyper. Värden med samma beteende kan ha olika representation! Exempel: val tab1 = update("a",1,update("b",2,empty)); val tab2 = update("b",2,update("a",1,empty)); tab1 och tab2 är nu bundna till tabeller med samma information. Men tab1 tab2, därför att listorna har elementen i olika ordning. För att förhindra misstag tillåter inte ML jämförelser mellan värden av abstrakta datatyper (utanför with... end). För att jämföra sådana värden måste man skriva en primitiv för jämförelsen som då kan ta hänsyn till att representationen skiljer. PK1&PM1 HT-06 moment 8 Sida 16 Uppdaterad 2005-09-22

Sammanfattning av abstraktion Definitionsabstraktion ett värde ersätts av ett symboliskt namn x < maximum i stället för x < 100 (vitsen är bättre läsbarhet och att behöver man ändra maximum räcker det med att ändra på ett ställe där maximum definieras.) Funktionsabstraktion ett uttryck görs oberoende av specifika data (fn x => x+1)y i stället för y+1 (vitsen är att (fn x => x+1) kan namnges och användas i många olika sammanhang ofta även bättre läsbarhet.) Dataabstraktion ett program görs oberoende av specifik datarepresentation update(x,y,table) i stället för (x,y)::table (vitsen är att man kan förändra representationen utan att ändra programmet, lättare att uppfylla invarianter, ofta bättre läsbarhet.) PK1&PM1 HT-06 moment 8 Sida 17 Uppdaterad 2005-09-22

Trädrepresentation Tabellinformation kan lagras i träd i stället för i listor. 4 2 7 1 6 9 Varje nod innehåller en nyckel och motsvarande värde. Detta träd representerar en tabell med nycklarna 1, 2, 4, 6, 7 och 9. (Här och i fortsättningen visas bara nycklarna i figurerna inte värden.) PK1&PM1 HT-06 moment 8 Sida 18 Uppdaterad 2005-09-22

Binära sökträd Ett binärt träd kallas för ett binärt sökträd om den har invarianten: Alla noder i vänster delträd har nycklar med lägre värden än rotnodens nyckel. Alla noder i höger delträd har nycklar med högre värden än rotnodens nyckel Dessa villkor gäller även för varje delträd 4 2 7 1 6 9 PK1&PM1 HT-06 moment 8 Sida 19 Uppdaterad 2005-09-22

Sökning i binära sökträd Sök efter nyckeln 6. Starta vid roten. Vid varje nod väljer man vänster eller höger sökträd beroende på om det man söker efter är mindre eller större än nodens nyckel. 4 större 2 7 mindre 1 6 9 träff PK1&PM1 HT-06 moment 8 Sida 20 Uppdaterad 2005-09-22

Deklaration av binära sökträd abstype (''a,'b) table = Empty Bintree of ''a*'b*(''a,'b) table*(''a,'b) table (* REPRESENTATION CONVENTION: Ett tomt träd representeras av Empty. Varje icketomt träd representeras av Bintree(k,v,l,r), där k är nyckeln, v är tabellvärdet, l är vänster delträd och r är höger delträd. REPRESENTATION INVARIANT: Alla nycklar i vänster resp. höger delträd måste vara mindre resp. större än k *) with (* empty TYPE: (''a*'b) table VALUE: Ett tomt träd *) val empty = Empty; fun update...; fun lookup...; fun remove...; fun tolist...; end; PK1&PM1 HT-06 moment 8 Sida 21 Uppdaterad 2005-09-22

Funktionen lookup (* lookup(key,table) TYPE: (Se kommentar nedan) PRE: table är ett sökträd POST: SOME v om key finns i table och v är motsvarande värde. NONE annars. *) (* VARIANT: Största djupet hos ett löv i table *) fun lookup(key,empty) = NONE lookup(key,bintree(key',value,left,right)) = if key = key' then SOME value else if key < key' then lookup(key,left) else lookup(key,right); Man skulle önska att typen hos lookup var ''a*(''a,'b) table -> 'b option, men i praktiken blir den int*(int,'a) table -> 'a option (se bild 25) PK1&PM1 HT-06 moment 8 Sida 22 Uppdaterad 2005-09-22

Körexempel lookup(6,bintree(4,"v4", Bintree(2,"v2", Bintree(1,"v1",Empty,Empty), Empty), Bintree(7,"v7", Bintree(6,"v6",Empty,Empty), Bintree(9,"v9",Empty,Empty)))) > if 6 = 4 then SOME "v4" else if 6 < 4 then lookup(6,bintree(2,"v2", Bintree(1,"v1",Empty,Empty), Empty)) else lookup(6,bintree(7,"v7", Bintree(6,"v6",Empty,Empty), Bintree(9,"v9",Empty,Empty))) PK1&PM1 HT-06 moment 8 Sida 23 Uppdaterad 2005-09-22

Körexempel (forts.) > lookup(6,bintree(7,"v7", Bintree(6,"v6",Empty,Empty), Bintree(9,"v9",Empty,Empty))) > if 6 = 7 then SOME "v7" else if 6 < 7 then lookup(6,bintree(6,"v6",empty,empty)) else lookup(6,bintree(9,"v9",empty,empty)) > if 6 = 6 then SOME "v6" else if 6 < 6 then lookup(6,empty) else lookup(6,empty) > SOME "v6" PK1&PM1 HT-06 moment 8 Sida 24 Uppdaterad 2005-09-22

Ett problem med typerna Läser man in programmet för binära sökträd i ML så ser man att typen för t.ex. lookup blir int * (int, 'a) table -> 'a option...alltså inte polymorf i nyckeltypen! Anledningen är att ML måste storleksjämföra nycklar och därför känna till deras typ. Vårt program fungerar bara med en bestämd nyckeltyp. (Inte nödvändigtvis int alla typer som kan storleksjämföras, t.ex. string, kan också användas.) Detta problem kan man lösa med högre ordningens funktioner (kursmoment 9). PK1&PM1 HT-06 moment 8 Sida 25 Uppdaterad 2005-09-22

Tidkomplexitet för binära sökträd Om alla nivåer i trädet är fyllda så innehåller ett träd med n nivåer 2 n -1 noder. För att söka efter en nyckel behöver man bara besöka så många noder som motsvarar antalet nivåer. Antalet rekursiva anrop för ett träd 2 n -1 noder är alltså n. Tidsåtgången är proportionell mot logaritmen av antalet nycklar O(log n). Ett träd med en miljon nycklar kräver c:a 20 rekursiva anrop av lookup jämför med 500 000 som krävdes när tabellen representerades som en lista. Detta förutsätter att trädet är välbalanserat mera senare... PK1&PM1 HT-06 moment 8 Sida 26 Uppdaterad 2005-09-22

Uppdatering av binära sökträd För att sätta in nyckeln 3: Sök efter den och sätt in den där den borde ha funnits: 4 mindre 2 hittar inte 7 1 3 6 9 ny nod PK1&PM1 HT-06 moment 8 Sida 27 Uppdaterad 2005-09-22

Funktionen update (* update(key,value,table) TYPE: ''a*'b*(''a,'b) table -> (''a,'b) table PRE: table är ett sökträd POST: Tabellen table uppdaterad med värdet value för nyckeln key *) (* VARIANT: största djupet av ett löv i table *) fun update(key,value,empty) = Bintree(key,value,Empty,Empty) update(key,value, Bintree(key',value',left,right)) = if key = key' then Bintree(key,value,left,right) else if key < key' then Bintree(key',value', update(key,value,left),right) else Bintree(key',value', left,update(key,value,right)); PK1&PM1 HT-06 moment 8 Sida 28 Uppdaterad 2005-09-22

Obalans Sätter man i tur och ordning in 1, 2, 4, 6, 7 och 9 i ett tomt sökträd så får man: 1 2 4 6 7 9 Detta är ett kraftigt obalanserat träd. I praktiken en lista, vilket ger samma tidsåtgång för sökning som i en lista linjärt i storleken. För att binära sökträd skall vara praktiskt användbara måste de balanseras om efter uppdateringar. Balanserade sökträd behandlas i nästa kurs (AD1/PK2). PK1&PM1 HT-06 moment 8 Sida 29 Uppdaterad 2005-09-22

Funktionen tolist Ibland vill man hämta ut informationen i ett träd som en lista. (* tolist table TYPE: (''a,'b) table-> (''a*'b) list PRE: (inget) POST: En lista av alla nyckel-värde-par i tabellen i inorder. *) (* VARIANT: Största djupet av något löv i table *) fun tolist Empty = [] tolist(bintree(key,value,left,right)) = tolist left @ (key,value) :: tolist right; tolist går igenom (traverserar) hela trädet för att samla information från noderna och bygga en lista. I detta fall besöker man vänster delträd först, sedan rotnoden, sedan höger delträd inorder-traversering. PK1&PM1 HT-06 moment 8 Sida 30 Uppdaterad 2005-09-22

Mer om traversering tolist besöker vänster delträd först, sedan rotnoden, sedan höger delträd inorder-traversering. Notera att listan som tolist returnerar är sorterad. Genom att bygga ett sökträd med en mängd data och sedan göra om det till en lista i inorder så har man sorterat datamängden! preorder-traversering man besöker först rotnoden, sedan vänster delträd, sedan höger. postorder-traversering man besöker först vänster delträd, sedan höger, sedan rotnoden. PK1&PM1 HT-06 moment 8 Sida 31 Uppdaterad 2005-09-22