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

Relevanta dokument
F4: Mer om OU1, OU2, listor och träd. Carl Nettelblad

Föreläsning 9 Datastrukturer (DAT037)

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

Föreläsning Datastrukturer (DAT036)

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.

Föreläsning 9 Innehåll

Föreläsning 10 Datastrukturer (DAT037)

F6: Debriefing OU2, OU3 Hashtabeller, användargränssnitt, interaktivitet och grafik. Carl Nettelblad

Tentamen Programmeringsteknik 2 och MN Skrivtid: Inga hjälpmedel.

Föreläsning 9 Innehåll

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

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

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

Föreläsning 5 Datastrukturer (DAT037)

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

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

Dugga Datastrukturer (DAT036)

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

Föreläsning 4 Datastrukturer (DAT037)

Länkade strukturer, parametriserade typer och undantag

F3: OU2, undantag, avbildningar, listor och träd. Carl Nettelblad

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

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

Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din anmälningskod överst i högra hörnet på alla papper.

Tentamen Datastrukturer, DAT037 (DAT036)

Föreläsning 4 Datastrukturer (DAT037)

Abstrakta datatyper. Primitiva vektorer. Deklarera en vektor

public boolean containskey(string key) { return search(key, head)!= null; }

Tentamen Datastrukturer (DAT036/DAT037/DIT960)

Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din anmälningskod överst i högra hörnet på alla papper.

Grafik, grafiska användargränssnitt och rörliga bilder

Föreläsning 8. Mängd, Avbildning, Hashtabell

Föreläsning Datastrukturer (DAT036)

Datastrukturer. föreläsning 6. Maps 1

Lösningsförslag till tentamen Datastrukturer, DAT037,

TENTAMEN: Algoritmer och datastrukturer. Läs detta!

Lösningsförslag till exempeltenta 1

Algoritmer och datastrukturer 2012, fo rela sning 8

Datastrukturer. föreläsning 10. Maps 1

Träd Hierarkiska strukturer

Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din kod överst i högra hörnet på alla papper.

Tentamen Datastrukturer D DAT 035/INN960

Observera. Tentamen Programmeringsteknik II Skrivtid:

Föreläsning Datastrukturer (DAT036)

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å

Algoritmer och datastrukturer

Sökning och sortering

Klassen BST som definierar binära sökträd med tal som nycklar och enda data. Varje nyckel är unik dvs förekommer endast en

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

Tentamen Programmeringsteknik II Skrivtid: Hjälpmedel: Java-bok (vilken som helst) Skriv läsligt! Använd inte rödpenna!

Föreläsning 13. Träd

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

Tentamen Programmeringsteknik II Skrivtid: Hjälpmedel: Java-bok (vilken som helst) Skriv läsligt! Använd inte rödpenna!

Föreläsning Datastrukturer (DAT037)

Avbildningar och hashtabeller. Koffman & Wolfgang kapitel 7, mestadels avsnitt 2 4

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

Tentamen, Algoritmer och datastrukturer

Trädstrukturer och grafer

Föreläsning 14 Innehåll

Tentamen Programmeringsteknik II Inledning. Anmälningskod:

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)

Tentamen Datastrukturer, DAT037 (DAT036)

F7: Rekursiv till iterativ, sammanfattning, genomgång av omtentan Carl Nettelblad

Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din kod överst i högra hörnet på alla papper.

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

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.

Tentamen Datastrukturer (DAT036)

Tentamen Datastrukturer (DAT036)

Tentamen Programmeringsteknik II och NV2 (alla varianter) Skriv bara på framsidan av varje papper.

DAI2 (TIDAL) + I2 (TKIEK)

Föreläsning 8. Mängd, Avbildning, Hashtabell

Lösningsförslag till tentamen Datastrukturer, DAT037,

Föreläsning 3 Datastrukturer (DAT037)

Programmering för Språkteknologer II. Innehåll. Associativa datastrukturer. Associativa datastrukturer. Binär sökning.

TENTAMEN: Algoritmer och datastrukturer. Läs detta!

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

Föreläsning 11 Innehåll

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

Programmering fortsättningskurs

Tentamen Datastrukturer (DAT037)

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

Interfacen Set och Map, hashtabeller

Programmering för språkteknologer II, HT2014. Rum

Föreläsning 10 Innehåll

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

Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din kod överst i högra hörnet på alla papper.

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 10 Innehåll. Prioritetsköer och heapar. ADT Prioritetskö. Interface för Prioritetskö. Exempel på vad du ska kunna

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

Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din anmälningskod överst i högra hörnet på alla papper.

Tommy Färnqvist, IDA, Linköpings universitet. 1 ADT Map/Dictionary Definitioner Implementation... 2

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

Föreläsning 4 Innehåll. Abstrakta datatypen lista. Implementering av listor. Abstrakt datatypen lista. Abstrakt datatyp

Diskutera. Hashfunktion

Programmering för språkteknologer II, HT2011. Rum

Föreläsning 10 Innehåll

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

Objektorienterad Programkonstruktion. Föreläsning 9 30 nov 2016

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

Tentamen i Algoritmer & Datastrukturer i Java

Transkript:

F5: Debriefing OU2, repetition av listor, träd och hashtabeller Carl Nettelblad 2017-04-24

Frågor Kommer nog inte att täcka 2 timmar Har ni frågor på OU3, något annat vi har tagit hittills på kursen, listor och träd specifikt? Fundera, så tar vi dem i helgrupp eller framme vid tavlan mot slutet

Recursive descent Gå från vänster till höger Titta bara på nästa token Rekursera ned olika djupt Var upptäcks de flesta fel? Längst ut Metoderna returnerar innan hela uttrycket är tolkat Längst in Primary fastnar på något den inte förstår

Hur hantera fel? (T.ex.) primary vet precis vad som gått fel Vet inte hur man kom dit Rapportera precis vad felet Med egna undantagsklasser Syntaxfel Ett viss uttryck är alltid felaktigt Evalueringsfel Att faktiskt beräkna uttrycket, just nu, går inte

Fånga felen Fånga undantag har två syften Rapportera felet I vårt fall, ta med info om aktuellt token i rapporten Hantera felet Vad gör vi nu? Hela programmet ska inte avslutas, ska fortsätta fungera normalt Exempel: Läsa till slutet av raden» Kunde vara stänga filer, starta om en bana, nollställa en beräkning, parkera en styrd utrustning i ett säkert läge, logga ut användaren

Kompilatorfel eller oväntade resultat vid körning Sätt att hantera fel Oväntat resultat/krasch Rapporterat undantag Hitta fel i förberedda tester Hitta fel i kompilering

Primary public double primary() { double result = 99999; if (tokenizer.isnumber()) { result = tokenizer.getnumber(); tokenizer.nexttoken(); } else return result; } Vad händer om vi missar att sätta result i ett fall? Får 99999 vid körning

Kompilatorfel eller oväntade resultat vid körning Sätt att hantera fel Oväntat resultat/krasch Rapporterat undantag Hitta fel i förberedda tester Hitta fel i kompilering

Primary public double primary() { double result = 99999; if (tokenizer.isnumber()) { result = tokenizer.getnumber(); tokenizer.nexttoken(); } else } else { throw new SyntaxException("unhandled case in primary"); } return result; } Vad händer om vi missar ett fall?

Kompilatorfel eller oväntade resultat vid körning Sätt att hantera fel Oväntat resultat/krasch Rapporterat undantag Hitta fel i förberedda tester Hitta fel i kompilering

Primary public double primary() { double result; if (tokenizer.isnumber()) { result = tokenizer.getnumber(); tokenizer.nexttoken(); } else return result; } Vad händer om vi missar att sätta result i ett fall? Kompileringsfel! Otilldelad variabel

Kompilatorfel eller oväntade resultat vid körning Sätt att hantera fel Oväntat resultat/krasch Rapporterat undantag Hitta fel i förberedda tester Hitta fel i kompilering

functionhelper private double functionhelper(string name, double val) { if (name.equals("cos")) { return Math.cos(val); } else if (name.equals("sin")) { return Math.sin(val); } } else { return Math.log(val); } } Vad händer om name inte är något av de godkända namnen?

Kompilatorfel eller oväntade resultat vid körning Sätt att hantera fel Oväntat resultat/krasch Rapporterat undantag Hitta fel i förberedda tester Hitta fel i kompilering

functionhelper private double functionhelper(string name, double val) { if (name.equals("cos")) { return Math.cos(val); } else if (name.equals("sin")) { } return Math.sin(val); } else if (name.equals("log")) { return Math.log(val); } else { throw new SyntaxException("Function " + name + " not supported."); } }

Kompilatorfel eller oväntade resultat vid körning Sätt att hantera fel Oväntat resultat/krasch Rapporterat undantag Hitta fel i förberedda tester Hitta fel i kompilering

Länkade listor Låt varje element peka på sin efterföljare Precis som ArrayList finns LinkedList i Java I många fall är ArrayList bäst Men inte om man vill lägga till/ta bort element någon annanstans än nära slutet

Fler varianter Dubbellänkad, cirkulär lista Lättare att nå sista elementet, lättare att röra sig bakåt i listan Men alla algoritmer krångligare

Klasser för länkade listor Precis som ArrayList finns LinkedList i Java Men nu ska vi inte använda den! Vi ska skriva vår egen klass Övning för att själv kunna skapa mer avanceade grafer och datastrukturer Övning i rekursivt tänkande En listan kan vara Tom Eller ett element, som i sig pekar på en lista

Exempel på enkellänkad lista Varje element pekar på sin efterföljare Inte föregångare! Hitta föregångare lika dyrt som att hitta visst index Varje element representeras med klassen Node Rekursiv definition, en Node har en referens till en (annan?) Node class Node { int data; Node next; }

Klassen List public class List { private Node first; private Node last; // Optional

Klassen List public class List { private static class Node { int data; Node next; Inre klass. Vilken skillnad gör static? } Node(int d, Node n) { data = d; next = n; } private Node first; private Node last; // Optional...

tostring public String tostring() { } return "[" + tostring(first) + "]"; private static String tostring(node n) { if (n==null) { return ""; } else { return n.data + " " + tostring(n.next); } } Varför static? Vanligt mönster med hjälpmetod som vandrar rekursivt genom elementen Skulle kunna skrivas iterativt också, ibland svårare

Dubbellänkad cirkulär Många operationer möjliga, men alla algoritmer blir mer komplicerade och lagringen kräver mer minne Enkellänkad kan ofta vara enklast och effektivast Ibland med tillägget att listobjektet också håller reda på direktpekare till sistaelementet, och/eller totala antalet element

Hjälpmetoder Publika metoder finns för att ge ett tydligt kontrakt till omvärlden Så här använder du den här klassen Hjälpmetoderna finns för att ge dig en tydlig struktur inne i klassen Kan göra saker som är förbjudna utifrån Kan ta andra parametrar och returnera andra värden än de publika metoderna Klassmetoder (static) om all information finns i parametrarna och returvärdet

Träd Ett (rotat) träd är en mängd noder där En speciell nod kallas rot Övriga noder delas in i m disjunkta delmängder som i sin tur är rotade träd Rekursiv definition! Inga cykler Tydlig riktning på relation mellan noder

Binära träd Ett binärt träd är en mängd noder som antingen är tom eller som består av tre olika delmängder Exakt en nod: roten Vänster delträd Höger delträd Observera att vänster delträd kan vara tomt Höger delträd något annat än bara andra barnet

Operationer på träd Orientering, vandring mellan noderna Traversering, besök alla noder Preorder, postorder, inorder Sökning efter nodinnehåll eller position Inlägg/uttag av noder Sammanfogning av flera träd Mätning av höjd, bredd, antal noder, väglängd, balans

Representera binära träd i kod Precis som med listor skapar vi nodobjekt Som refererar till andra nodobjekt class Node { } int data; Node parent; Node left; Node right;... Förälderpekaren är ofta onödig, jämför enkellänkad/dubbellänkad lista.

Exempel: BinarySearchTree En klass som lagrar textsträngar som data i ett binärt träd Trädet är ett binärt sökträd, med följande regel för alla noder Varje nyckel (unik sträng) finns alltså endast en gång Praktisk struktur för sökning, inläggning och urtag Men inte oproblematisk

Nodrepresentation private static class Node { private String value; private Node left, right; } private Node(String value, Node left, Node right) { this.value = value; this.left = left; this.right = right; }

Placering av klassen public class BinarySearchTree { private static class Node {... } private Node root; public BinarySearchTree() { root = null; }

tostring public String tostring() { return tostring(root); } private static String tostring(node r) { if (r==null) { return ""; } else { return tostring(r.left) + " " + r.value + " " + tostring(r.right); } } Vilken typ av traversering är detta? Preorder, postorder, inorder?

Lämna till hjälpmetod public void add(string value) { root = add(root, value); } Lägga till element

Lägga till element private static Node add(node r, String value) { } if (r==null) { } return new Node(value,null,null); int compare = value.compareto(r.value); if (compare<0) { r.left = add(r.left, value); } else if (compare>0) { } r.right = add(r.right, value); return r; Fortsätt tills underträd saknas och lägg in ny nod där med värdet Låt jämförelse styra önskat värde Eller stanna om befintligt element har samma värde Jämför med likheterna i List

Egenskaper hos binära träd Ett binärt träd med k fyllda nivåer innehåller n noder n = 1 + 2 + 4 + + 2 k 1 = 2 k -1 k = log 2 (n + 1) log 2 n I ett sådant träd blir arbetet för Sökning O log n Inlägg O log n Uttag O log n

Sämsta möjliga träd I ett sådant träd blir arbetet för Sökning O n Inlägg O n Uttag O n Trädet en linjär lista Algoritmerna blir i praktiken som algoritmerna för enkellänkad

Vad händer för mitt träd? Vad gäller i genomsnitt? Vad är genomsnitt? I genomsnitt i ett genomsnittligt träd? Tre mått som påverkar trädets prestanda: Höjd ger rekursionsdjup i värsta möjliga fall Värsta möjliga höjd lika med antalet element Intern väglängd: för lyckad sökning Extern väglängd: för misslyckad sökning

Intern väglängd Intern väglängd (ipl, eller bara i) kan definieras som summan av nivån för alla noder Roten har nivå 1, rotens barn nivå 2, Exempel: i = 1 + 2 * 2 + 4 * 3 + 4 * 4 = 33 Att hitta en lagrad nyckel tar då i genomsnitt i n = 33 11 = 3 steg

Extern väglängd Extern väglängd (EPL, eller bara E) tar med externa noder dessutom Den externa väglängden definieras som summan av de externa nodernas nivåer (4 * 4 + 8 * 5 = 56 för exemplets 12 externa noder) Varje sökning efter en nyckel som inte finns slutar i en extern nod. Eftersom antalet externa noder är n + 1 blir det genomsnittliga antalet försök för misslyckad sökning E/(n + 1) Extra: Bevisa att antalet externa noder är n + 1 och att E = i + 2n + 1

Iläggningsordning Hur ett binärt träd växer beror på i vilken ordning noderna läggs i Praktiska implementationer kan ibland också balansera om trädet AVL-träd, rödsvarta träd En definition på hur bra trädet är blir hur välordnat det blir i medeltal över alla möjliga iläggningsordningar Den interna väglängden för alla träd som bildas om man lägger in alla n! permutationer av n nycklar blir 1,38 n log 2 n + O n I ett slumpmässigt träd tar då sökning O(log n) operationer

Binära sökträd i Java TreeSet<E>, TreeMap<K,V> är sådana ombalanserande binära träd. De garanterar O(log n) för inlägg, sökning och urtag för varje specifikt träd.

Alla binära träd är inte sökträd

Alla binära träd är inte sökträd Aritmetiska uttrycket 1 * (2 3) + (4 + 5)/6 Trädet styr evalueringsordning, inga parenteser Värdet beräknas genom att rekursivt: Beräkna värdet av vänster träd Beräkna värdet av höger träd Utföra operationen på de två beräknade värdena

OU3 Utgå från beskrivningen av enkellänkade listor och binära träd Fundera över vilka rekursiva hjälpmetoder som blir nyttiga Fundera över tidskomplexitet Se till att skriva egna testfall för BST, lita inte bara på automattesterna

Hashtabeller Vi har sett att man kan göra sökträd Oftast i en struktur är det viktiga att kunna lägga in, söka och ta bort Inte traversera i viss ordning Tidskomplexitet Lägg in Sök Ta bort Sorterad array Θ(n) Θ(log n) Θ(n) Länkad lista Θ(n) Θ(n) Θ(n) Binärt sökträd Θ(log n) Θ(log n) Θ(log n) Går det att göra bättre? Inte om vi bara kan jämföra enskilda element

Hashtabeller Vi kanske kan använda mer information än bara en sorterings-/jämförelseregel. Arrayer är snabba. Lagra alla element i en array, välj index utifrån en hashfunktion. Samma objekt leder alltid till samma hashvärde. Blir värdena alltid unika? Oftast inte. Hur gör man då? Leta efter en annan plats i arrayen. eller Använd en länkad lista för alla element som kolliderar. Vi tittar på alternativet med en länkad lista.

Heltal som element Tänk att vi har en liten tabell med 7 platser och hashfunktionen h(k) = k mod 7 (rest vid heltalsdivision) som hashfunktion. k 27 4 7 42 3 14 81 26 13 8 h(k) 6 4 0 0 3 0 4 5 6 1 Väljer att hålla listorna sorterade eftersom man vid inlägg ändå måste kontrollera att elementet inte redan är inlagt.

Tidskomplexitet Antag att vi vill lagra n nycklar i en array med m platser Den genomsnittliga listlängden blir då α = n m fyllnadsgraden som kallas Om α 1 och om hashfunktionen sprider elementen någorlunda jämnt över arrayen blir strukturen effektiv för inlägg, sökning och urtag. Misslyckad sökning: 1 + α försök Lyckad sökning: 1 + α 2 försök Fördjupad analys i separat dokument

Tidskomplexitet Om tabellstorleken ungefär motsvara antalet element och hashfunktionen ger bra spridning tar sökning, inlägg och urtag O(1) tid Nära på lika snabbt som vanlig array Trädstrukturer är O(log n) Dessutom är varje operation ofta dyrare

Skapa hashfunktioner Enormt viktiga att hashvärdet är någorlunda unikt Även när man tar modulo något mindre tal För heltal: h(k) = k Blir k mod m i praktiken för hashtabell storlek m Teckensträngar Konstruera ett heltal utifrån teckenkoderna, se mer i länkat dokument Ofta viktigt att samma teckenföljd i annan ordning inte får samma kod

Hashstrukturer i Java HashSet<E> HashMap<K, V> Ofta bättre (snabbare) än TreeSet, TreeMap Samma metoder Olika implementationer av gränssnitten (interface) Set och Map Går att skriva kod som ska ta en Map och sedan ge den antingen en TreeMap eller en HashMap Malin pratar mer om det nästa gång

Hashfunktioner i Java Java har inbyggda hashfunktioner Metoden int hashcode() finns i klassen Object Precis som tostring och equals Standardversionen beräknar hash utifrån referenslikhet D.v.s. om a == b har de också samma hashvärde I standardklasser som ersätter equals ersätts också hashcode Samma objekt bör inte byta hashvärde under sin livstid Tänk om du stoppar in ett objekt i en HashSet och sedan förändrar det så att det byter hashvärde

Sammanfattning Listor och träd är flexibla datastrukturer Grund för att komma fram till egna representationer Oerhört kraftfullt att ha objekt som refererar till objekt av samma typ Som Node Om du bara behöver en lista, använd ändå ArrayList Om du bara behöver en länkad lista, använd LinkedList HashMap och HashSet är bra grundval för att skapa avbildningar och lagra mängder Kräver korrekt implementation av hashcode och equals om referenslikhet inte räcker

Frågor?