Diskutera. Hashfunktion

Relevanta dokument
Föreläsning 10 Innehåll

Föreläsning 10 Innehåll. Diskutera. Hashtabeller. Hashfunktion. hashfunktion. hashkod (ett heltal)

Inlämningsuppgift och handledning

Inlämningsuppgift och handledning. Föreläsning 11 Innehåll. Diskutera. Hashtabeller

Interfacen Set och Map, hashtabeller

Föreläsning 11 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 14 Innehåll

Föreläsning 10 Innehåll

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

Föreläsning 9 Innehåll

Hitta k största bland n element. Föreläsning 13 Innehåll. Histogramproblemet

Tentamen, EDAA01 Programmeringsteknik fördjupningskurs

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

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

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

Programmering fortsättningskurs

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

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

Seminarium 3 Introduktion till Java Collections Framework Innehåll. Generik Bakgrund. Exempel på en generisk klass java.util.arraylist.

Seminarium 2 Introduktion till Java Collections Framework Innehåll. Generik Bakgrund. Exempel på en generisk klass java.util.arraylist.

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

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

Innehåll. Föreläsning 10. Specifikation. Mängd. Specifikation. Konstruktion av mängd. Mängd Lexikon Hashtabell

Datastrukturer som passar för sökning. Föreläsning 11 Innehåll. Binära sökträd Definition. Inordertraversering av binära sökträd

Seminarium 13 Innehåll

Datastrukturer som passar för sökning. Föreläsning 10 Innehåll. Inordertraversering av binära sökträd. Binära sökträd Definition

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

Samlingar Collection classes

Föreläsning 4 Innehåll

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

Objektorienterad Programmering DAT043. Föreläsning 9 12/2-18 Moa Johansson (delvis baserat på Fredrik Lindblads material)

Datastrukturer. föreläsning 6. Maps 1

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

Java Collections Framework. Föreläsning 2 Innehåll. Java Collections Framework interface hierarki. Java Collections Framework interface hierarki

Algoritmer och datastrukturer

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 5 Datastrukturer (DAT037)

Abstrakt datatyp. -Algoritmer och Datastrukturer- För utveckling av verksamhet, produkter och livskvalitet.

Föreläsning 13 Innehåll

Föreläsning 2 Innehåll

Tentamen, EDAA01 Programmeringsteknik fördjupningskurs

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

13 Prioritetsköer, heapar

Algoritmer och datastrukturer 2012, fo rela sning 8

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

Föreläsning 9 Datastrukturer (DAT037)

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

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

Föreläsning 2 Innehåll

Tentamen, EDAA01 Programmeringsteknik fördjupningskurs

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

Föreläsning 9 Innehåll

Länkade strukturer. (del 2)

Sortering. Föreläsning 12 Innehåll. Sortering i Java. Sortering i Java Exempel. Sortering

Föreläsning 12 Innehåll

Java Collections Framework. Föreläsning 2 Innehåll. Java Collections Framework interface hierarki. Java Collections Framework interface hierarki

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

Samlingar Collection classes

Magnus Nielsen, IDA, Linköpings universitet

Lösningsförslag till tentamen i EDA690 Algoritmer och Datastrukturer, Helsingborg

Föreläsning 4 Datastrukturer (DAT037)

Föreläsning Datastrukturer (DAT036)

Tentamen, EDA690 Algoritmer och Datastrukturer, Helsingborg

Lösningsförslag till tentamen i EDAA01 programmeringsteknik fördjupningkurs

Föreläsning 2 Innehåll. Generiska klasser. Generik i Java. Varför generiska klasser Bakgrund

Hashtabeller. TDA416, lp3 2016

Föreläsning 7 Innehåll. Rekursion. Rekursiv problemlösning. Rekursiv problemlösning Mönster för rekursiv algoritm. Rekursion. Rekursivt tänkande:

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

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

Länkade strukturer, parametriserade typer och undantag

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

Lösningsförslag till tentamen Datastrukturer, DAT037,

Föreläsning 10 Datastrukturer (DAT037)

ADT Kö. Seminarium 4 Köer och Stackar Innehåll. Operationer. ADT Stack. Definition. Definition

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

Föreläsning 11 Innehåll

Tentamen, EDAA01 Programmeringsteknik fördjupningskurs

Föreläsning 11 Innehåll. Sortering. Sortering i Java. Sortering i Java Comparable. Sortering. O(n 2 )-algoritmer: urvalssortering insättningssortering

Listor. Koffman & Wolfgang kapitel 2, avsnitt , och 2.9

Collection classes. Interface, första exempel. Interface (forts) Men först

Tentamen, Algoritmer och datastrukturer

Tentamen, EDAA01 Programmeringsteknik fördjupningskurs

Tentamen i Algoritmer & Datastrukturer i Java

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

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

Föreläsning 5 Innehåll

Datastrukturer. Arrayer. Arrayer. Arrayer. Array av arrayer. Array av arrayer

Datastrukturer. föreläsning 10. Maps 1

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 5 Erik Nilsson, Institutionen för Datavetenskap, LiU

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

Collection Classes. bjectorienterad programmering Sida 1

Lösningsförslag till exempeltenta 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

Datastrukturer och algoritmer

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

Datastrukturer. föreläsning 3. Stacks 1

Tentamen kl Uppgift 4. Uppgift 5

Föreläsning 5 Innehåll. Val av algoritm och datastruktur. Analys av algoritmer. Tidsåtgång och problemets storlek

Föreläsning 3-4 Innehåll. Diskutera. Metod. Programexempel med metod

Transkript:

Föreläsning 1 Innehåll Diskutera Hashtabeller implementering, effektivitet Metoden hashcode i Java Abstrakta datatyperna mängd (eng. Set) och lexikon (eng. Map) Interfacen Set och Map i Java Tidigare har vi sett att man kan använda binära sökträd för att lagra data som man snabbt ska kunna söka i. Tidskomplexiteten för att sätta in, söka och ta bort element i ett balanserat binärt sökträd är O(logn). Antag att vi har fått i uppdrag att skriva ett program som hanterar medlemmar i en förening. Antalet medlemmar är max 1000 st. Varje medlem har ett unikt medlemsnummer mellan 0 och 999. Detta nummer används som nyckel för att identifiera och söka efter en medlem. Finns det något bättre (snabbare, enklare) sätt än binärt sökträd för att lagra medlemmarna i just detta specialfall? Datavetenskap (LTH) Föreläsning 1 HT 017 1 / 57 Hashtabeller Datavetenskap (LTH) Föreläsning 1 HT 017 / 57 Hashfunktion Idé: översätt nycklar till heltal som kan användas som index i en vektor. Antag att de nycklar som ska användas vid sökningen är heltal i intervallet 0..n. En vektor med n + 1 platser kan användas. Elementet med nyckel k placeras på plats k i vektorn. Sökning, insättning och borttagning av k blir en direkt access till plats k. Alla dessa operationer har tidskomplexitet O(1). Idéen kan generaliseras till alla slags objekt: Nycklarna översätts till ett heltal i intervallet 0..n. Datavetenskap (LTH) Föreläsning 1 HT 017 3 / 57 nyckel hashfunktion hashkod (ett heltal) Hashfunktionen avbildar nyckeln på heltal (hashkod). hashkod % table.length kan användas som index i en vektor table. Kollisioner (olika nycklar får samma index) är oundvikliga och måste hanteras. En bra hashfunktion bör påverkas av alla delar av nyckeln. ger litet förväntat antal kollisioner, sprider elementen över hela tabellen. Datavetenskap (LTH) Föreläsning 1 HT 017 4 / 57

Hashfunktion för heltal Hashfunktion för strängar Om nyckeln är ett heltal k kan hashkoden vara talet självt. Index i vektorn räknas ut så här: int index = k % table.length; if (index < 0 ) { index : index + table.length; Math.abs kan ge ett negativt resultat och används därför inte här. För en sträng s0s1ssn 1 är en lämplig hashfunktion s[0] 31 n 1 + s[1] 31 n + + s[n 1] Ger ett stort heltal (som får anpassas till tabellens storlek genom % table.length). Tecken i olika positioner multipliceras med olika potenser av 31. Permutationer av samma tecken ger därför olika hashkod. 31 är ett primtal och det kan visas att man därför får relativt få kollisioner. Datavetenskap (LTH) Föreläsning 1 HT 017 5 / 57 Metoden hashcode Datavetenskap (LTH) Föreläsning 1 HT 017 / 57 Diskutera I klassen Object finns en metod hashcode som översätter ett objekt till ett heltal. Den är implementerad så att olika objekt om möjligt avbildas på olika heltal. Metoden hashcode är skuggad i Javas klasser (String, Integer ) så att lika objekt avbildas på samma heltal. Heltalet som returneras från hashcode får sedan anpassas till tabellens storlek med % table.length. Man måste skugga hashcode (och equals) i den klass vars objekt ska fungera som nyckel i en hashtabell. Objekt för vilka equals ger true ska få samma hashkod. Försök sätta in element med nycklarna 1, 8, 7, 4, ska sättas in i en tabell med 7 platser. Elementets index = x % 7. 0 1 3 4 5 Hur hanterar man kollisioner (dvs. att olika nycklar får samma index)? Datavetenskap (LTH) Föreläsning 1 HT 017 7 / 57 Datavetenskap (LTH) Föreläsning 1 HT 017 8 / 57

Hashtabeller olika alternativ Sluten hashtabell med linjär kollisionsteknik Det finns olika sätt att implementera hashtabeller. Sluten hashtabell (eng: open addressing) en vektor används för att lagra elementen Det finns sedan olika sätt att hantera kollisioner t ex linjär teknik kvadratisk teknik Öppen hashtabell (eng: separate chaining) en vektor av listor Kolliderande objekt placeras i samma lista. Vid linjär teknik sätter man in ett element som kolliderar med ett annat på första lediga plats efter den där det skulle ha hamnat om ingen kollision inträffat. Tabellen betraktas som cirkulär, d.v.s. index 0 anses komma efter tablesize-1. 1 8 4 7 0 1 3 4 5 Sökning efter visst element börjar på den plats elementets hashkod anger och fortsätter eventuellt framåt. Om det inte påträffas före en ledig plats finns det inte i tabellen. Datavetenskap (LTH) Föreläsning 1 HT 017 9 / 57 Borttagning i sluten hashtabell med linjär kollisionsteknik Datavetenskap (LTH) Föreläsning 1 HT 017 10 / 57 Borttagning i sluten hashtabell med linjär kollisionsteknik Forts Om vi vid borttagning bara gör platsen tom, leder det till fel vid sökning. Ex: Tag bort 1 ur tabellen på föregående bild: 8 4 7 0 1 3 4 5 Om vi nu söker efter 8 vars hashkod % 7 är 1 börjar vi pröva plats 1. Eftersom denna plats är tom sluter vi oss felaktigt till att det sökta elementet inte finns i tabellen. Om vi i stället markerar platsen icke-aktiv vid borttagning (i fig. nedan markerat med ett d): d 8 4 7 0 1 3 4 5 så kan vi utföra sökningen med början på den plats hashkod % 7 anger och framåt över alla upptagna och icke-aktiva platser. Först när vi stöter på en riktigt tom plats är det misslyckad sökning. Datavetenskap (LTH) Föreläsning 1 HT 017 11 / 57 Datavetenskap (LTH) Föreläsning 1 HT 017 1 / 57

Tidskomplexitet, linjär teknik Problem med linjär teknik Sökning (och därmed insättning och borttagning) i en hashtabell innebär beräkning av index sökning bland kolliderande element Värstafallet för operationerna sökning, insättning och borttagning är O(n), där n är antalet element som finns insatta i tabellen. Inträffar om alla element hamnar i en följd och vi t ex vid sökning måste pröva alla platserna i denna följd. Är dock ytterst osannolikt. Under förutsättning att tabellen inte fylls till mer än hälften får man O(1)-komplexitet i medeltal. Linjär teknik ger upphov till primär klustring i tabellen. Om flera objekt kolliderar (får samma index pos) kommer de att ligga i ett kluster kring platsen pos. Även objekt vars hashkoder är nära pos kommer att drabbas av kollisioner och bygga ut klustret. Stora kluster gör sökning långsam. Ex: Sätt in element med nycklarna 3, 13, 3, 33, 5, 15. 3 13 3 33 0 1 3 4 5 5 15 7 8 9 Datavetenskap (LTH) Föreläsning 1 HT 017 13 / 57 Sluten hashtabell, kvadratisk kollisionsteknik Datavetenskap (LTH) Föreläsning 1 HT 017 14 / 57 Sluten hashtabell, kvadratisk kollisionsteknik Exempel Alternativ, bättre teknik för hantering av kollisioner. Först prövas nästa plats, sedan platsen 4 steg fram, sedan 9 steg fram, alltså pos, pos + 1, pos +, pos + 3,, pos + i, där pos är elementets hashkod. Tabellen används fortfarande cirkulärt. Undviker primär klustring av element. Kan modifieras till andra sekvenser av steg. Sätt in element med nycklarna 89, 18, 49, 58, 9 i en tabell med 10 platser. 89 % 10 = 9 18 % 10 = 8 49 % 10 = 9 58 % 10 = 8 9 % 10 = 9 49 58 9 0 1 3 4 5 7 18 89 8 9 Datavetenskap (LTH) Föreläsning 1 HT 017 15 / 57 Datavetenskap (LTH) Föreläsning 1 HT 017 1 / 57

Sluten hashtabell, kvadratisk kollisionsteknik Öppen hashtabell (separate chaining) Problem: Inte alltid säkert att man hittar ledig plats även om det finns. Om t ex tabellens storlek är 1 och man använder hashfunktionen x % 1 och sätter in element med nycklarna 0, 1, 3 och 4 så kan man inte därefter hitta någon ledig plats för element som hashas till plats 0. De enda platser som kommer att prövas i serien pos + i när pos = 0 blir de upptagna platserna 0, 1, 4 och 9. Om tabellens storlek är ett primtal kan ett nytt element alltid sättas in om tabellens fyllnadsgrad är mindre än 0.5. Tidskomplexitet: Ännu ej fullständigt utredd. Värsta fallet är O(n). I praktiken mindre klustring än den linjära tekniken. Elementen i tabellen är listor. I lista nummer k ligger alla element vars nyckel har hashkod % table.length = k. 0 1 table.length- table.length-1 Datavetenskap (LTH) Föreläsning 1 HT 017 17 / 57 Öppen hashtabell (separate chaining) Exempel Datavetenskap (LTH) Föreläsning 1 HT 017 18 / 57 Nycklar och hashkod Blanda inte ihop begreppen Sätt in element med nycklarna 1, 8, 7, 4, i en öppen tabell med 7 listor. 0 1 4 8 1 3 4 5 7 Nycklarna är unika. Hashkoden beräknas med en hashfunktion som avbildar nycklarna på heltal. Som index i vektorn används hashkod % table.length I Java: key.hashcode() % table.length Olika nycklar kan få samma index (kollision). 0 1 3 4 5 4 8 1 7 Unika nycklar: 4, 8, 1 samma index: 1 Unika nycklar:, 7 samma index: Datavetenskap (LTH) Föreläsning 1 HT 017 19 / 57 Datavetenskap (LTH) Föreläsning 1 HT 017 0 / 57

Öppen hashtabell Diskutera Obeservera att borttagning i öppen tabell är enklare än i sluten. Elementet tas helt enkelt bort ur den lista där det befinner sig. Vi får inga problem med luckor som i den slutna tabellen. I Javas klassbibliotek används öppna tabeller i klasserna HashSet och HashMap. Vilka faktorer påverkar antal kollisioner i en hashtabell? Vilka konsekvenser får ett högt antal kollisioner i en (öppen) hashtabell? Hur kan risken för kollisioner minskas? På laboration 5 får du implementera en öppen hashtabell med enkellänkade listor. Datavetenskap (LTH) Föreläsning 1 HT 017 1 / 57 Tidskomplexitet, öppen tabell Datavetenskap (LTH) Föreläsning 1 HT 017 / 57 Rehashing Om fyllnadsgraden blir för stor måste man bygga om tabellen: Värstafallet för operationerna sökning, insättning och borttagning är O(n), där n är antalet element som finns insatta i tabellen. Inträffar om alla element hamnat i samma lista. Medelfall Tidskomplexiteten är O(1) i medelfall (och i praktiken med en bra hashfunktionen och med en tillräckligt stor tabell). Fyllnadsgrad (eng. load factor) = antal insatta element/antal platser i tabellen. Valet av fyllnadsgrad är en kompromiss mellan minnesåtgång och tidsåtgång. Ett lämpligt val av fyllnadsgrad är 0.75. Skapa en dubbelt så stor tabell. Sätt in alla element i den nya tabellen. 0 1 3 4 5 4 8 1 5 7 0 1 3 4 5 7 8 9 10 11 1 13 1 8 5 7 4 Datavetenskap (LTH) Föreläsning 1 HT 017 3 / 57 Datavetenskap (LTH) Föreläsning 1 HT 017 4 / 57

ADT Mängd Använda binärt sökträd för att implementera ADT mängd Definition En mängd (eng. Set) är en en samling element där dubbletter är förbjudna. Operationer: sätta in ett element ta bort ett element undersöka om ett element finns i mängden Ett balanserat binärt sökträd passar bra att använda för att representera en mängd: Ett binärt sökträd innehåller inte dubbletter. Det är effektivt att sätta in ett element ta bort ett element undersöka om ett element finns i trädet. Tidskomplexiteten för dessa operationer är O( log n) i ett balanserat binärt sökträd. Datavetenskap (LTH) Föreläsning 1 HT 017 5 / 57 Använda hashtabell för att implementera ADT mängd Datavetenskap (LTH) Föreläsning 1 HT 017 / 57 ADT Lexikon En hashtabell passar bra att använda för att representera en mängd: Ett hashtabell innehåller inte dubbletter. Det är effektivt att sätta in ett element. ta bort ett element. undersöka om ett element finns i hashtabellen. Tidskomplexiteten för dessa operationer är O(1) i medelfall (och i praktiken vid bra val av hashfunktion och tabellstorlek). Definition Ett lexikon (eng. Map) är en en samling element där varje element har en en nyckel och ett värde. Nycklarna är unika. Operationer: sätta in ett nyckel-värde-par ta bort ett nyckel-värde-par söka värdet som hör till en nyckel Datavetenskap (LTH) Föreläsning 1 HT 017 7 / 57 Datavetenskap (LTH) Föreläsning 1 HT 017 8 / 57

ADT lexikon (Map) ADT lexikon (Map) Exempel I ett lexikon (Map) betraktas element som tvådelade en nyckel och tillhörande värde. Nyckeln avbildas (eng. maps) på sitt värde. Nycklar är unika, men inte värden. Man använder nyckeln för att söka tillhörande värde. Exempel: nyckel = månad, värde = antal dagar i månaden. nyckel = personnummer, värde = Person-objekt med namn, adress. nycklar (unika) mars april maj värden (dubbletter ok) 31 30 31 Datavetenskap (LTH) Föreläsning 1 HT 017 9 / 57 Diskutera Datavetenskap (LTH) Föreläsning 1 HT 017 30 / 57 Använda binärt sökträd för att implementera ADT lexikon Hur kan vi använda ett binärt sökträd eller en hashtabell för att implementera en Map? I ett binärt sökträd kan vi sätta in element, inte par (nyckel, värde). Men vi kan ändå använda ett binärt sökträd. Vi deklarerar en nästlad klass som representerar par (nyckel,värde) och sätter in objekt av denna typ i trädet. Vid jämförelser (i metoden compareto) är det nycklarnas värden som ska jämföras. data left right key value Datavetenskap (LTH) Föreläsning 1 HT 017 31 / 57 Datavetenskap (LTH) Föreläsning 1 HT 017 3 / 57

Använda hashtabell för att implementera ADT lexikon Interfacen Set och Map i java.util Man kan deklarera en nästlad klass som representerar nyckel-värde-par och sätta in sådana objekt i hashtabellen. Hashkoden beräknas på nyckeln. Iterable Collection 0 1 3 4 null null null null key value next key value next null Queue List Set Map 5 null key value null next SortedSet SortedMap Datavetenskap (LTH) Föreläsning 1 HT 017 33 / 57 Interfacet Set Datavetenskap (LTH) Föreläsning 1 HT 017 34 / 57 Interfacet SortedSet En mängd (Set) är en samling element som inte innehåller dubbletter. Metoderna i interfacet Set finns även i interfacet Collection. De har dock olika kontrakt genom att Set inför restriktionen att inga dubbletter får förekomma. Enligt specifikationen i Java får en mängd (Set) innehålla null-element. Men bara ett null-element, p.g.a. dubblettförbudet. Vissa konkreta implementeringar av interfacet Set i java.util förbjuder dock insättning av null. Förutsätter att elementen som sätts in går att jämföra med varandra. Elementen ska antingen implementera interfacet Comparable eller genom att man (via konstruktorn) anger ett Comparator-objekt som kan användas för jämförelser. Vi återkommer till detta. Garanterar att operationen iterator() returnerar en iterator som går igenom mängden i växande ordning. Utvidgar Set-interfacet med några operationer som återspeglar att elementen går att ordna. Exempel: returnera minsta element, returnera största... Datavetenskap (LTH) Föreläsning 1 HT 017 35 / 57 Datavetenskap (LTH) Föreläsning 1 HT 017 3 / 57

Klasser som implementerar Set TreeSet implementerar det utvidgade interfacet SortedSet. Använder ett slags balanserat träd, inte AVL-träd utan röd-svarta träd (eng. Red-Black trees), som också garanterar att höjden är O( log n). HashSet Använder hashtabell. Set Interfacet Set Abstrakta klasser AbstractCollection Collection Set betyder ärver från ("extends") betyder implementerar ("implements") SortedSet AbstractSet SortedSet HashSet TreeSet HashSet TreeSet Datavetenskap (LTH) Föreläsning 1 HT 017 37 / 57 Interfacet Set Abstrakta klasser Kommentarer till hierarkin på föregående bild: Interface fick t.o.m. Java 7 inte innehålla implementeringar. Ibland kan man implementera vissa operationer med hjälp av andra operationer i samma interface. Ex: isempty size() == 0 För att underlätta för den som ska implementera ett (stort) interface kan man implementera en abstrakt klass som innehåller implementeringar av vissa metoder enligt detta mönster. Ex: klasserna AbstractCollection och AbstractSet Implementatören av en konkret klass kan då ärva den abstrakta klassen och behöver sedan bara implementera återstående operationer i interfacet. Ex: klasserna TreeSet och HashSet. Fr.o.m Java 8 får man ha default-metoder i interface. Det innebär att man nu hade kunnat lägga de metoder som implementeras i Abstractklasserna direkt i interfacen istället. Datavetenskap (LTH) Föreläsning 1 HT 017 39 / 57 Datavetenskap (LTH) Föreläsning 1 HT 017 38 / 57 Klassen TreeSet Implementerar interfacet SortedSet. Det finns flera konstruktorer i klassen, bl.a: 1 public TreeSet(); public TreeSet(Comparator<? super E> c); Används den första konstruktorn, förutsätts elementen implementera Comparable annars genereras ClassCastException. Den andra konstruktorn har en parameter som är ett objekt av en klass som implementerar interfacet Comparator. Används denna kommer jämförelser att utföras med hjälp av komparatorn. Datavetenskap (LTH) Föreläsning 1 HT 017 40 / 57

Exempel på användning av klassen TreeSet Comparable<E> // Denna mängd kommer att ordnas efter personnummer Set<Person> nbrset = new TreeSet<Person>(); nbrset.add(new Person("Kalle", "34009-134")); nbrset.add(new Person("Kajsa", "370109-1")); // undersök om personen med personnummer 370109-1 // finns i mängden boolean found = nbrset.contains(new Person(null, "370109-1")); Klassen Person måste implementera Comparable<Person>. I metoden compareto jämförs personernas personnummer. Datavetenskap (LTH) Föreläsning 1 HT 017 41 / 57 Exempel på användning av klassen HashSet Exempel på användning av klassen TreeSet Komparator // Denna mängd kommer att ordnas efter namn Set<Person> nameset = new TreeSet<Person>(new NameComparator()); nameset.add(new Person("Kalle", "34009-134")); nameset.add(new Person("Kajsa", "370109-1")); Klassen NameComparator måste implementeras. I metoden compare jämförs personernas namn. public class NameComparator implements Comparator<Person> { public int compare(person p1, Person p) { return p1.getname().compareto(p.getname()); Istället för en comparatorklass kan man använda lambdauttryck: Set<Person> nameset = new TreeSet<Person>((p1, p) -> p1.getname().compareto(p.getname())); Datavetenskap (LTH) Föreläsning 1 HT 017 4 / 57 Skugga metoderna equals och hashcode Antag vi vill vill sätta in Person-objekt i en mängd av typen HashSet. HashSet<Person> set = new HashSet<Person>(); Person p = new Person("Kajsa", "370109-1"); set.add(p); boolean found = set.contains(new Person(null, "370109-1")); Nu måste equals och hashcode skuggas i klassen Person. I equals ska personnumren jämföras. I hashcode ska en hashkod för personnumret beräknas. Inuti klasserna HashSet och HashMap används metoderna hashcode() och equals(object) för att hitta ett element: Först beräknas index för elementet med nyckel key med key.hashcode() % table.length. Sedan söks key i listan på denna plats. I samband med denna sökning används equals. Datavetenskap (LTH) Föreläsning 1 HT 017 43 / 57 Datavetenskap (LTH) Föreläsning 1 HT 017 44 / 57

Om man glömmer skugga hashcode Klass som skuggar equals och hashcode Klassen Person Om vi glömmer att skugga hashcode i Person hittar vi troligen inte personen: När personen p sätts in beräknas hashkoden för objektet som p refererar till. När vi söker efter personen baseras sökningen på hashkoden av det objekt som är parameter till contains-metoden. Detta är ett annat objekt (men med samma personnummer). Sökningen utgår från den plats denna senare hashkod anger och med största sannolikhet är det i en helt annan del av tabellen än den där personen sattes in. Datavetenskap (LTH) Föreläsning 1 HT 017 45 / 57 Interfacet Map i java.util AbstractMap HashMap Map SortedMap TreeMap Datavetenskap (LTH) Föreläsning 1 HT 017 47 / 57 public class Person { private String name; private String pnbr; // konstruktor och övriga metoder public boolean equals(object other) { if (other instanceof Person) { return pnbr.equals(((person) other).pnbr); else { return false; public int hashcode() { return pnbr.hashcode(); Datavetenskap (LTH) Föreläsning 1 HT 017 4 / 57 Interfacet Map - ett urval av metoderna public interface Map<K,V> { V get(object key); boolean isempty(); V put(k key, V value); V remove(object key); int size(); Set<K> keyset(); Collection<V> values(); Set<Map.Entry<K,V>> entryset(); public interface Entry<K,V> { K getkey(); V getvalue(); V setvalue(v); Interfacet Map ärver inte interfacet Collection eller Iterable. Det går alltså inte att iterera direkt över mappen. Däremot kan man iterera över nycklarna, värdena och nyckel-värdeparen. Datavetenskap (LTH) Föreläsning 1 HT 017 48 / 57

Klasser som implementerar Map Exempel på användning av klassen TreeMap TreeMap implementerar interfacet SortedMap. Använder balanserat binärt sökträd (röd-svart träd) keyset().iterator() ger en iterator som går igenom nycklarna i växande ordning. Ytterligare operationer som bygger på ordning mellan nycklarna finns. HashMap Använder öppen hashtabell. Map Map<String, Integer> map = new TreeMap<String, Integer>(); map.put("januari", 31); map.put("februari", 8); map.put("mars", 31); map.put("april", 30); map.put("maj", 31); System.out.println("Antal dagar i mars: " + map.get("mars")); HashMap SortedMap TreeMap I en TreeMap är det nyckelklassen som ska implementera Comparable eller vars attribut ska jämföras i en komparatorklass. I exemplet har nycklarna typen String. Klassen String implementerar Comparable<String>. Datavetenskap (LTH) Föreläsning 1 HT 017 49 / 57 Exempel på användning av klassen TreeMap, forts Datavetenskap (LTH) Föreläsning 1 HT 017 50 / 57 Interfacet Map.Entry En Map används normalt för att med nyckeln hitta motsvarande värde. Ibland behöver man göra tvärtom: System.out.println("Månader med 31 dagar:"); for (Map.Entry<String, Integer> e : map.entryset()) { if (e.getvalue() == 31) { System.out.println(e.getKey()); Metoden entryset returnerar en mängd med alla nyckel-värde-par. Genom att traversera denna mängd kan vi ta reda på vilka nyckel-värde-par som har värdet 31 och skriva ut motsvarande nyckel. Map.Entry är ett inre interface som är nästlat i interfacet Map. /* Representerar ett nyckel-värdepar */ public interface Entry<K,V> { K getkey(); V getvalue(); V setvalue(v); // ändrar värdet till V och // returnerar det gamla värdet Operationen entryset returnerar en mängd (Set) av Entry-objekt. d.v.s. objekt av en klass som implementerar interfacet Map.Entry Datavetenskap (LTH) Föreläsning 1 HT 017 51 / 57 Datavetenskap (LTH) Föreläsning 1 HT 017 5 / 57

Exempel på användning av klassen HashMap Exempel 1 Exempel på användning av klassen HashMap Exempel Map<String, Integer> map = new HashMap<String, Integer>(); map.put("januari", 31); map.put("februari", 8); map.put("mars", 31); map.put("april", 30); map.put("maj", 31); System.out.println("Antal dagar i mars: " + map.get("mars")); I en HashMap måste nyckelklassen skugga equals och hashcode. I exemplet har nycklarna typen String. Klassen String skuggar equals och hashcode. Antag vi vill vill sätta in Person-objekt i en hashtabell (HashMap). Personens personnummer ska vara nyckel. Map<String, Person> map = new HashMap<String, Person>(); map.put("370109-1", new Person("Kajsa", "370109-1")); Person p = map.get("370109-1"); if (p!= null) { Här har nycklarna typen String, och i denna klass är redan equals och hashcode skuggade. Datavetenskap (LTH) Föreläsning 1 HT 017 53 / 57 Exempel på vad du ska kunna Förklara begreppen hashtabell och hashfunktion. Definiera vad som menas med sluten och öppen hashtabell och hur kollisioner hanteras i sådana tabeller. Förklara vad som menas med fyllnadsgraden (eng: load factor) för en hashtabell. Förklara hur sökning, insättning och borttagning går till i slutna respektive öppna hashtabeller. Implementera öppna hashtabeller (görs på laboration 5). Ange tidskomplexiteten för operationer på hashtabell. Förklara vad de abstrakta datatyperna set och map är och vilka operationer man förväntas kunna utföra på dem. Använda interfacen Set och Map och deras implementerande klasser i Java Collections Framework. Datavetenskap (LTH) Föreläsning 1 HT 017 54 / 57 Datorlaboration 5 Binära sökträd Implementera en egen generisk klass för binära sökträd. 4 5 9 8 Tips: I flera fall blir det en (kort) publik metod som anropar en privat rekursiv metod. I en av metoderna ska ett nytt träd byggas upp från värden i en vektor. Hämta inspiration från den rekursiva algoritmen för binärsökning. Rita för att förstå vad som händer i programmet! Innehåll: binära sökträd, rekursion, länkad struktur. Datavetenskap (LTH) Föreläsning 1 HT 017 55 / 57 Datavetenskap (LTH) Föreläsning 1 HT 017 5 / 57

Datorlaboration 5, forts Insättning i binära sökträd Nycklarna i vänster subträd < roten < nycklarna i höger subträd Dubbletter är ej tillåtna. Nya noder sätts alltid in som löv. Insättning börjar med en (förhoppningsvis) misslyckad sökning. Exempel: Sätt in 3. Börja här: 5 9 4 Misslyckad sökning! Sätt in 3 här. 8 Datavetenskap (LTH) Föreläsning 1 HT 017 57 / 57