Föreläsning 10 Innehåll

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

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

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

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

Föreläsning 11 Innehåll

Diskutera. Hashfunktion

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

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

Interfacen Set och Map, hashtabeller

Föreläsning 9 Datastrukturer (DAT037)

Tentamen, EDAA01 Programmeringsteknik fördjupningskurs

Föreläsning 14 Innehåll

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

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

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

Föreläsning Datastrukturer (DAT036)

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

Seminarium 3 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

Seminarium 13 Innehåll

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

Algoritmer och datastrukturer 2012, fo rela sning 8

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

Föreläsning 9 Innehåll

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

Föreläsning 13 Innehåll

Tentamen, EDAA01 Programmeringsteknik fördjupningskurs

Datastrukturer. föreläsning 10. Maps 1

Programmering fortsättningskurs

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

Föreläsning 2 Innehåll

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

Samlingar Collection classes

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

13 Prioritetsköer, heapar

Föreläsning 10 Datastrukturer (DAT037)

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

Algoritmer och datastrukturer

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

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

Tentamen, EDAA01 Programmeringsteknik fördjupningskurs

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

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

Föreläsning 4 Innehåll

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

Föreläsning 3 Innehåll

Diskutera Sortera objekt

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

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

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

Tentamen, EDA690 Algoritmer och Datastrukturer, Helsingborg

Föreläsning 2 Innehåll

Föreläsning 4 Datastrukturer (DAT037)

Tentamen, Algoritmer och datastrukturer

Datastrukturer. föreläsning 10. Maps 1

Tentamen, EDAA01 Programmeringsteknik fördjupningskurs

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

Föreläsning 5 TDDC91,TDDE22,725G97: DALG. Föreläsning i Datastrukturer och algoritmer 18 september 2018

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

Samlingar Collection classes

Lösningsförslag till tentamen Datastrukturer, DAT037,

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

Föreläsning Datastrukturer (DAT036)

Föreläsning 12 Innehåll

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

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

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

Lösningar Datastrukturer TDA

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

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

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

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

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

BST implementering, huvudstruktur

Lösningsförslag till tentamen Datastrukturer, DAT037,

Länkade strukturer. (del 2)

Tentamen, EDAA01 Programmeringsteknik fördjupningskurs

Datastrukturer. föreläsning 9. Maps 1

Tentamen Programmeringsteknik II Inledning. Anmälningskod:

Föreläsning 5 Innehåll

Föreläsning Datastrukturer (DAT036)

Länkade strukturer, parametriserade typer och undantag

Collection Classes. bjectorienterad programmering Sida 1

Datastrukturer. föreläsning 3. Stacks 1

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

Tentamen Datastrukturer (DAT036/DAT037/DIT960)

Föreläsning 11 Innehåll

Lösningsförslag till exempeltenta 1

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

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

Begreppet subtyp/supertyp i Java. Mera om generik. Generik och arv. Generik och arv. Innehåll

Programkonstruktion och. Datastrukturer

Träd Hierarkiska strukturer

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

Transkript:

Föreläsning 10 Innehåll Binära sökträd algoritmer för sökning, insättning och borttagning implementering Jämföra objekt interfacet Comparable Interfacet Comparator Balanserade binära sökträd, AVL-träd tidseffektivitet Klasserna TreeSet och TreeMap i Java Collection Framework Datavetenskap (LTH) Föreläsning 10 VT 2020 1 / 65

Datastrukturer som passar för sökning Antag att vi i ett program ska hantera ett stort antal element av något slag. Det ska gå snabbt att sätta in ett element ta bort ett element söka efter ett visst element Vilken/vilka datastrukturer passar bra för detta? vektor, enkellänkad lista insättning snabb O(1) sökning (linjärsökning) och borttagning långsamma O(n) sorterad vektor sökning (binärsökning) snabb O(logn) insättning och borttagning långsamma O(n) Det finns datastrukturer som passar bättre för detta: Binära sökträd Hashtabeller Datavetenskap (LTH) Föreläsning 10 VT 2020 2 / 65

Binära sökträd Definition Ett binärt sökträd är ett binärt träd där följande gäller för varje nod n: Alla värden som finns i noder i vänster subträd till n är mindre än värdet som finns i n. Alla värden som finns i noder i höger subträd till n är större än värdet som finns i n. Dubbletter tillåts alltså inte. 5 2 9 4 6 8 Datavetenskap (LTH) Föreläsning 10 VT 2020 3 / 65

Inordertraversering av binära sökträd Genomgång av trädet i inorder besöker noderna i växande ordning. Exempel: En inordertraversering av trädet i figuren ger noderna i ordningen 2, 4, 5, 6, 8, 9 5 2 9 4 6 8 Datavetenskap (LTH) Föreläsning 10 VT 2020 4 / 65

Binära sökträd sökning Då man söker efter ett element i ett binärt sökträd kan man utnyttja ordningen i trädet: Börja i roten, jämför med sökt element x, om likhet är vi klara. Om x är mindre än rotens element: gå till vänster barn annars gå till höger barn. Fortsätt på samma sätt tills vi hittar det sökta, eller tills den nod som står i tur att undersökas är null (misslyckad sökning). Man följer alltså en gren i trädet: Grenen börjar i roten. Man fortsätter tills man hittar det sökta eller till grenen tar slut (misslyckad sökning). Datavetenskap (LTH) Föreläsning 10 VT 2020 5 / 65

Binära sökträd - sökning Exempel Sök efter 6 i trädet: Sök efter 3 i trädet: Börja här: 5 Börja här: 5 2 9 2 9 4 6 Klart! 4 6 8 Misslyckad sökning! 8 Datavetenskap (LTH) Föreläsning 10 VT 2020 6 / 65

Diskutera Hur går insättning i ett binärt sökträd till? Var i trädet ska 3 sättas in? Var i trädet ska 7 sättas in? 5 2 9 4 6 8 Datavetenskap (LTH) Föreläsning 10 VT 2020 7 / 65

Binära sökträd - insättning Exempel Sätt in 3 i trädet: Efter insättning: Börja här: 5 5 2 9 2 9 4 6 4 6 Misslyckad sökning! Sätt in 3 här. 8 3 8 Datavetenskap (LTH) Föreläsning 10 VT 2020 8 / 65

Binära sökträd - insättning Exempel Sätt in 6 i trädet: Börja här: 5 2 9 4 6 8 Dubblett hittas. Insättningen genomförs inte. Datavetenskap (LTH) Föreläsning 10 VT 2020 9 / 65

Binära sökträd insättning Sammanfattning Vid insättning av nytt element ska ordningen i trädet bevaras. Dubbletter får inte förekomma. Insättning kan tolkas som misslyckad sökning : Vi söker på en gren i trädet. Om vi misslyckas med hitta det element som ska sättas in utförs insättningen som ett löv på den plats i trädet där misslyckandet konstaterats. Datavetenskap (LTH) Föreläsning 10 VT 2020 10 / 65

Binära sökträd borttagning För att kunna ta bort ett element ur trädet måste vi söka upp det. När vi tar bort det måste vi koppla ihop föräldern med något av barnen. Vid sökningen behöver man därför hålla reda på en referens till föräldern. Sammankopplingen sköts på olika sätt beroende på hur många barn som finns till den nod som ska bort: Enklaste fallen är noll eller ett barn. Fallet två barn är lite krångligare. Datavetenskap (LTH) Föreläsning 10 VT 2020 11 / 65

Binära sökträd - borttagning Exempel på enkelt fall - noll barn Tag bort 3 ur trädet. Börja med att söka efter noden (och föräldern). parent = null act 5 Noden, act, som ska bort är ett löv. Sätt den referens i parent som refererar till act till null. 5 2 9 2 9 parent act 3 4 6 8 4 6 8 Datavetenskap (LTH) Föreläsning 10 VT 2020 12 / 65

Binära sökträd - borttagning Exempel på enkelt fall - ett barn Tag bort 4 ur trädet. Börja med att söka efter noden (och föräldern). parent = null act 2 5 9 Noden, act, som ska bort har ett barn. Sätt den referens i parent som refererar till act till att referera till act:s barn. 5 parent act 4 6 2 9 3 8 3 6 8 Datavetenskap (LTH) Föreläsning 10 VT 2020 13 / 65

Binära sökträd - borttagning Exempel - två barn Tag bort 2 ur trädet. Noden, act, som ska bort har två barn: parent act 2 5 9 Sök upp minsta noden (min) i act:s högra subträd 1 4 6 Flytta data från denna till act min 3 8 Tag bort min Datavetenskap (LTH) Föreläsning 10 VT 2020 14 / 65

Binära sökträd - borttagning Exempel - två barn, forts Efter flyttning av data från min till act: Efter borttagning av min: 5 5 3 9 3 9 1 4 6 1 4 6 8 min 3 8 Observera att borttagning av min är ett enklare fall eftersom denna nod kan ha högst ett barn (höger). Datavetenskap (LTH) Föreläsning 10 VT 2020 15 / 65

Implementering av binära sökträd Klassen BinarySearchTree Exempel på hur en klass som representerar ett binärt sökträd kan se ut: public class BinarySearchTree<E> { private Node<E> root; private int size; public BinarySearchTree() { root = null; } public boolean add(e e) {...} public E find(e x) {...} public boolean remove(e x){...}... } // nästlad klass Node<E> med attributen data, left och right // som representerar en nod... Datavetenskap (LTH) Föreläsning 10 VT 2020 16 / 65

Implementering av binära sökträd Exempel på ett binärt sökträd med elementen 27, 8, 64: root size 3 data left right 27 8 data left right null null data left null right null 64 Datavetenskap (LTH) Föreläsning 10 VT 2020 17 / 65

Sökning i binärt sökträd pseudokod E find(n, x) { om n == null) return null annars om x är lika med n return n; annars om x är mindre än n return find(n, x) // sök i vänster subträd annars return find(n, x) // sök i höger subträd Anropas find(root, x) Datavetenskap (LTH) Föreläsning 10 VT 2020 18 / 65

Diskutera Hur ska jämförelserna mellan två element i trädet gå till? om x är lika med n om x är mindre än n Datavetenskap (LTH) Föreläsning 10 VT 2020 19 / 65

Metoden find public E find(e x) { return find(root, x); } private E find(node<e> n, E x) { if (n == null) { return null; } int compresult = ((Comparable<E>) x).compareto(n.data); if (compresult == 0) { return n.data; } else if (compresult < 0) { return find(n.left, x); } else { return find(n.right, x); } } Datavetenskap (LTH) Föreläsning 10 VT 2020 20 / 65

Interfacet Comparable Repetition Metoden compareto i interfacet Comparable används inuti add, find och remove för att jämföra två element. public interface Comparable<T> { /** * Compares this object with the specified object for order. * Returns a negative integer, zero, or a positive integer as * this object is less than, equal to, or greater than the * specified object. */ public int compareto(t x); } Datavetenskap (LTH) Föreläsning 10 VT 2020 21 / 65

Kommentarer Klassen som ersätter E måste implementera Comparable<E>. Annars genereras ClassCastException när find exekveras. För att anropet av compareto ska fungera måste vi typkonvertera x till Comparable<E>:... ((Comparable<E>) x).compareto(n.data)... En annan lösning är att vid deklarationen av typparametern E kräva att klassen som ersätter E implementerar Comparable<E>: public class BinarySearchTree<E extends Comparable<E>> { Då behövs ingen typkonvertering vid anropet av compareto... x.compareto(n.data)... Datavetenskap (LTH) Föreläsning 10 VT 2020 22 / 65

Exempel på användning av klassen BinarySearchTree // Skapa ett träd sorterat efter idnummer BinarySearchTree<Person> bst = new BinarySearchTree<Person>(); bst.add(new Person("Fili", 1)); bst.add(new Person("Balin", 2));... // sök efter personen med idnummer 2 Person p = bst.find(new Person(null, 2); Klassen Person måste implementera Comparable<Person>. Observera att man måste skapa ett Person-objekt för att kunna söka efter en person i trädet. Detta objekt måste få korrekta värden på de attribut som används för jämförelser i compareto. Datavetenskap (LTH) Föreläsning 10 VT 2020 23 / 65

Implementering av interfacet Comparable Klassen Person public class Person implements Comparable<Person> { private String name; private int id;... } public int compareto(person other) { return Integer.compare(id, other.id); // eller id - other.id; } Comparable är ett generiskt interface. I exemplet är Person typargument. Observera att parametern i compareto därför har typen Person. Datavetenskap (LTH) Föreläsning 10 VT 2020 24 / 65

Diskutera Klassen Person implementerar nu interfacet Comparable och i metoden compareto jämförs id-nummer. Hur ska vi göra om vi vill ha en mer flexibel lösning och kunna skapa träd ordnade efter något annat än id-nummer? Antag t.ex. att vi också vill kunna skapa ett träd ordnat efter personernas namn (eller något/några andra attribut)? Datavetenskap (LTH) Föreläsning 10 VT 2020 25 / 65

Interfacet Comparator Vi ska se till att det finns ett alternativ till compareto för att jämföra element inuti trädklassen. Interfacet Comparator ger oss möjlighet att jämföra objekt av en klass på flera olika sätt. public interface Comparator<T> { /** * Compares its two arguments for order. * Returns a negative integer, zero, or a positive * integer as the first argument is less than, * equal to, or greater than the second. */ int compare(t e1, T e2); } Datavetenskap (LTH) Föreläsning 10 VT 2020 26 / 65

Konstruktor med parameter av typen Comparator Klassen BinarySearchTree public class BinarySearchTree<E> { private Node<E> root; private int size; private Comparator<E> comp; /** Skapar ett tomt binärt sökträd. Elementen förutsätts vara av en klass som implementerar Comparable<E>. */ public BinarySearchTree() { root = null; comp = null; } /** Skapar ett tomt binärt sökträd. Elementen jämförs med komparatorn comp. */ public BinarySearchTree(Comparator<E> comp) { root = null; this.comp = comp; } Datavetenskap (LTH) Föreläsning 10 VT 2020 27 / 65

Metod för att välja mellan compareto och compare privat metod i klassen BinarySearchTree... private int compareelements(e e1, E e2) { if (comp == null) { return ((Comparable<E>) e1).compareto(e2); } else { return comp.compare(e1, e2); } }... Datavetenskap (LTH) Föreläsning 10 VT 2020 28 / 65

Metoden find Användning av metoden compareelements public E find (E x) { return find(root, x); } private E find(node<e> n, E x) { if (n == null) { return null; } int compresult = compareelements(x, n.data); if (compresult == 0) { return n.data; } else if (compresult < 0) { return find(n.left, x); } else { return find(n.right, x); } } // nytt Datavetenskap (LTH) Föreläsning 10 VT 2020 29 / 65

Två konstruktorer Nu har klassen två konstruktorer: 1 public BinarySearchTree(); 2 public BinarySearchTree(Comparator<? super E> c); Används den första konstruktorn, förutsätts elementen implementera Comparable annars genereras ClassCastException. Inuti trädklassen används metoden compareto för att jämföra två objekt. Den andra konstruktorn har en parameter av typen Comparator. Vid anrop skickar man med ett lambdauttryck/en referens till ett objekt av en klass som implementerar interfacet Comparator. Används denna kommer jämförelser att utföras med hjälp av komparatorns metod compare. Datavetenskap (LTH) Föreläsning 10 VT 2020 30 / 65

Skapa komparator-objekt med lambdauttryck // Skapa ett träd sorterat efter namn BinarySearchTree<Person> bst = new BinarySearchTree<Person>( (p1, p2) -> p1.getname().compareto(p2.getname()) ); bst.add(new Person("Fili", 1)); bst.add(new Person("Balin", 2));... // sök efter personen med namnet Balin Person p = bst.find(new Person(Balin, -1); Interfacet Comparator<E> är ett funktionellt interface, d.v.s. den har bara en abstrakt metod. I sådana fall kan man använda lambdauttryck istället för att skriva en klass som implementerar interfacet skapa ett objekt av denna klass och skicka med en referens till ett sådant objekt som argument. Datavetenskap (LTH) Föreläsning 10 VT 2020 31 / 65

Skapa komparator-objekt längre version Skriv en komparatorklass som implementerar interfacet Comparator: public class NameComparator implements Comparator<Person> { public int compare(person p1, Person p2) { return p1.getname().compareto(p2.getname()); } } Skapa ett objekt av komparatorklassen och skicka med som argument till konstruktorn i trädklassen: BinarySearchTree<Person> bst = new BinarySearchTree<Person>(new NameComparator()); Datavetenskap (LTH) Föreläsning 10 VT 2020 32 / 65

Vad betyder? super E Överkurs? super E kan utläsas okänd superklass till E (inklusive E) Typen Comparator<? super E> bör användas i trädklassen istället för Comparator<E>. Förklaring: Antag att vi har följande klasser: class Person {... } class Student extends Person {... } class NameComparator implements Comparator<Person> {... } Om Comparator<E> används inuti trädklassen kan vi inte skriva: BinarySearchTree<Student> bst = new BinarySearchTree<Student>(new NameComparator()); Det finns ingen klass som implementerar Comparator<Student>. Istället lättar vi på på kravet och kräver att komparatorklassen istället ska implementera Comparator<? super E>. Då kan vi skapa studentträdet eftersom Person är superklass till Student. Datavetenskap (LTH) Föreläsning 10 VT 2020 33 / 65

Diskutera En traversering genom alla noderna i ett träd med n noder har tidskomplexiteten O(n). Varje nod besöks en gång. Men vad påverkar effektiviteten för operationerna sökning, insättning och borttagning? Vad får dessa metoder för tidskomplexitet? Datavetenskap (LTH) Föreläsning 10 VT 2020 34 / 65

Binära sökträd tidskomplexitet Operationerna sökning, insättning och borttagning innebär sökning utmed en gren i trädet. I varje nod görs ett konstant arbete (väsentligen en jämförelse). Den längsta grenen i ett träd har h noder, där h är trädets höjd. Värsta fall för samtliga operationer är alltså O(h). Vi vill uttrycka tidskomplexiteten som en funktion av antal noder, n. Vi måste alltså känna till sambandet mellan trädet höjd och antal noder. Datavetenskap (LTH) Föreläsning 10 VT 2020 35 / 65

Samband mellan höjd och antal noder i binära träd För alla binära träd T med n noder gäller för höjden h h n (1) och h 2 log(n + 1) (2) (1) är enkelt att inse. Trädet får största möjliga höjd om man placerar en nod på varje nivå. Höjden blir då n. Ex. för n = 3: Datavetenskap (LTH) Föreläsning 10 VT 2020 36 / 65

Samband mellan höjd och antal noder i binära träd, forts (2): På nivå ett finns en nod (roten). På nivå två högst 2 noder, på nivå tre högst 4 nodet etc. Allmänt finns det på nivå i högst 2 i 1 noder. Den högsta nivån i ett träd med höjd h är h. = antal noder, n 1 + 2 + 4 +... + 2 i 1 +... + 2 h 1 = 1 2h 1 2 = 2h 1. Vilket ger att h 2 log(n + 1) Här har vi använt formeln för geometrisk summa: 1 + a + a 2 +... + a k = 1 ak+1 1 a Datavetenskap (LTH) Föreläsning 10 VT 2020 37 / 65

Binära sökträd tidskomplexitet Samtliga operationer (sökning, insättning, borttagning) innebär sökning utmed en gren i trädet. I varje nod görs ett konstant arbete (väsentligen en jämförelse). Den längsta grenen i ett träd har h noder, där h är trädets höjd. Värsta fall för samtliga operationer är alltså O(h). Vi har tidigare visat att för alla binära träd med n noder gäller att 2 log(n + 1) höjden n De tre operationerna har tidskomplexitet O(n) i värsta fall och O( 2 log n) i bästa fall. Datavetenskap (LTH) Föreläsning 10 VT 2020 38 / 65

Diskutera Sätt in 1, 2,... 7 (i den ordningen) Sätt in 4, 2, 1, 6, 5, 3, 7: Sätt in 2, 5, 1, 6, 7, 3, 4: Vilken insättningsordning ger bästa respektive sämsta formen på trädet? Datavetenskap (LTH) Föreläsning 10 VT 2020 39 / 65

Binära sökträd tidskomplexitet, forts Trädets höjd påverkas av insättningar och borttagningar. I värsta fall består trädet av en enda gren och värstafallstiden för sökning, insättning och borttagning blir O(n). Vid slumpmässiga insättningar och borttagningar blir tidskomplexiteten i medelfall O( 2 log n). Vi ska strax se hur man kan hålla trädet balanserat och även få en värstafallstid på O( 2 log n). Datavetenskap (LTH) Föreläsning 10 VT 2020 40 / 65

Binära sökträd med minimal höjd Den idealiska formen på ett binärt sökträd: Alla nivåer, utom möjligen den högsta, har så många noder som är möjligt. Det betyder att noderna ligger så nära roten som möjligt. Då blir trädets höjd garanterat O( 2 log n). Datavetenskap (LTH) Föreläsning 10 VT 2020 41 / 65

Exempel på binära träd med minimal höjd Ett binärt träd är perfekt (eng: perfect binary tree) om alla noder utom löven har två barn och om alla löven befinner sig på samma nivå. Då har trädet formen: Ett binärt träd är komplett (eng: complete binary tree) om alla nivåer utom den högsta är fyllda med noder och om noderna på den högsta nivån är samlade längst till vänster. Då har trädet formen: Datavetenskap (LTH) Föreläsning 10 VT 2020 42 / 65

Binära sökträd - tidskomplexitet Det finns ingen tillräckligt effektiv algoritm för att se till att ett binärt sökträd får den idealiska formen. Trädet behöver inte ha denna form för att garantera att alla operationer blir O( 2 log n) i värsta fall. Det räcker att garantera att höjden är proprtionell mot 2 log n, d.v.s. att h = O( 2 log n). Det finns effektiva algoritmer för att i samband med insättning och borttagning garantera att trädets höjd alltid är O( 2 log n). Datavetenskap (LTH) Föreläsning 10 VT 2020 43 / 65

Balanserade binära sökträd AVL-träd Georgy Adelson-Velsky and Evgenii Landis gjorde följande definition: Balanserat binärt träd Ett binärt träd är balanserat om det för varje nod i trädet gäller att höjdskillnaden mellan dess båda subträd är högst ett. De visade också att I balanserade träd är höjden h 1.44 2 log n. Det finns effektiva algoritmer för att se till att binära sökträd förblir balanserade vid insättningar och borttagningar. Datavetenskap (LTH) Föreläsning 10 VT 2020 44 / 65

Balanserade binära sökträd Balanserat träd Obalanserat träd Datavetenskap (LTH) Föreläsning 10 VT 2020 45 / 65

Balanserade binära sökträd balans = h R h L h R = höger subträds höjd h L = vänster subträds höjd 1 1 1 1 0 1 1 2 0 0 0 0 0 0 0 0 0 Balanserat träd Obalanserat träd Datavetenskap (LTH) Föreläsning 10 VT 2020 46 / 65

Diskutera Vad händer med trädets balansering om man lägger till 2? Hur kan man rätta till det? 0 1 20 0 0 10 50 0 0 5 40 60 Datavetenskap (LTH) Föreläsning 10 VT 2020 47 / 65

Balansering av binära sökträd Exempel Balanseringsalgoritmerna arbetar med rotationer i trädet: Obalanserat vid 10: Efter en enkel högerrotation: 1 0 2 20 0 0 20 0 1 10 50 0 0 0 5 0 50 0 0 5 40 60 2 10 40 60 0 2 Datavetenskap (LTH) Föreläsning 10 VT 2020 48 / 65

Balansering av binära sökträd Exempel - dubbelrotationer Ibland behövs dubbelrotationer: Obalanserat vid 10: Efter en vänster-högerrotation: 1 0 20 20 2 0 0 0 10 50 7 50 1 2 0 0 0 0 0 0 1 5 0 40 60 5 10 40 60 7 Datavetenskap (LTH) Föreläsning 10 VT 2020 49 / 65

Balansering av binära sökträd kostnad Man kan visa att: Om obalans uppstår till följd av en insättning i ett tidigare balanserat träd så räcker det med en enkel- eller dubbelrotation för att återställa balansen. Om obalans uppstår till följd av en borttagning ur ett tidigare balanserat träd så kan det behövas en enkel- eller dubbelrotation i varje nod på vägen från den nod där obalans uppstod till roten för att återställa balansen. Datavetenskap (LTH) Föreläsning 10 VT 2020 50 / 65

Balansering av binära sökträd kostnad Höjden förblir O( 2 log n) om man balanserat trädet vid varje förändring. En enskild rotation kostar bara O(1). Kostnaden för balansering i samband med en insättning eller borttagning är O( 2 log n). Om ett binärt sökträd hålls balanserat kommer sökning, insättning och borttagning därmed att kosta O( 2 log n) i värsta fall. Datavetenskap (LTH) Föreläsning 10 VT 2020 51 / 65

Javas trädklasser I Java Collection Framework finns klasserna TreeSet Implementerar den abstrakta datatypen Mängd (eng. Set). Elementen är unika. TreeMap Implementerar den abstrakta datatypen Map (nyckel-värde-tabell). Nycklarna är unika. Inuti bägge klasserna används 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( 2 log n). Förutsätter att elementen/nycklarna som sätts in går att jämföra med varandra (Comparable/Comparator). En iterator går igenom en mängd av typen TreeSet i ordning. Datavetenskap (LTH) Föreläsning 10 VT 2020 52 / 65

Klasserna TreeSet och TreeMap i java.util <<Interface>> Iterable <<Interface>> Collection <<Interface>> Queue <<Interface>> List <<Interface>> Set <<Interface>> Map <<Interface>> SortedSet <<Interface>> SortedMap TreeSet HashSet TreeMap HashMap Datavetenskap (LTH) Föreläsning 10 VT 2020 53 / 65

Interfacet Set Inklusive de abstrakta klasserna <<Interface>> Collection betyder ärver från ("extends") AbstractCollection <<Interface>> Set betyder implementerar ("implements") AbstractSet <<Interface>> SortedSet HashSet TreeSet Datavetenskap (LTH) Föreläsning 10 VT 2020 54 / 65

Interfacet Set Abstrakta klasser Kommentarer till hierarkin på föregående bild: Ibland kan man implementera vissa metoder med hjälp av andra metoder. Ex: public boolean isempty() { return 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. Detta har gjorts i klasserna AbstractCollection och AbstractSet. Om man ska skriva en klass som implementerar interfacet Set kan man då ärva den abstrakta klassen AbstractSet och behöver sedan bara implementera återstående metoder i interfacet. Datavetenskap (LTH) Föreläsning 10 VT 2020 55 / 65

Klassen TreeSet Det finns flera konstruktorer i klassen, bl.a: 1 public TreeSet(); 2 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 av typen Comparator. Vid anrop skickar man med ett lambdauttryck. Viktigaste metoderna: sätta in add(element) ta bort remove(element) undersöka om ett element finns i mängden contains(element) Datavetenskap (LTH) Föreläsning 10 VT 2020 56 / 65

Exempel på användning av klassen TreeSet Comparable<E> // Denna mängd kommer att ordnas efter idnummer Set<Person> nbrset = new TreeSet<Person>(); set.add(new Person("Fili", 1)); set.add(new Person("Balin", 2));... // Undersök om personen med idnummer 2 finns i mängden System.out.println(set.contains(new Person(null, 2))); Klassen Person måste implementera Comparable<Person>. I metoden compareto jämförs personernas personnummer. Datavetenskap (LTH) Föreläsning 10 VT 2020 57 / 65

Exempel på användning av klassen TreeSet Comparator - lambdauttryck // Denna mängd kommer att ordnas efter namn Set<Person> nameset = new TreeSet<Person>((p1, p2) -> p1.getname().compareto(p2.getname())); set.add(new Person("Fili", 1)); set.add(new Person("Balin", 2));... // Undersök om personen med namnet Balin finns i mängden System.out.println(set.contains(new Person("Balin", -1))); Datavetenskap (LTH) Föreläsning 10 VT 2020 58 / 65

Abstrakt datatypen Map Repetition En map innehåller nyckel-värde-par Nyckeln avbildas (eng. maps) på sitt värde. Nycklarna är unika, men inte värdena. Man använder nyckeln för att söka tillhörande värde. Exempel: nyckel = månad, värde = antal dagar i månaden. nycklar (unika)... mars april maj... värden (dubbletter ok)... 31 30 31... Datavetenskap (LTH) Föreläsning 10 VT 2020 59 / 65

Implementera en map Lagra nyckel och värde tillsammans i ett objekt När man ska implementera en map behöver man lagra nyckel och värde tillsammans. En nästlad klass kan användas för att representera ett nyckel-värde-par. Vid sökningar är det nycklarna som jämförs. Skiss som visar hur det skulle kunna se ut: root size 12 data left right key value "April" 30 Datavetenskap (LTH) Föreläsning 10 VT 2020 60 / 65

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ärde-paren. Datavetenskap (LTH) Föreläsning 10 VT 2020 61 / 65

Exempel på användning av klassen TreeMap Map<String, Integer> map = new TreeMap<String, Integer>(); map.put("januari", 31); map.put("februari", 28); map.put("mars", 31); map.put("april", 30); map.put("maj", 31);... System.out.println("Antal dagar i mars: " + map.get("mars")); I en TreeMap är det nyckelklassen som ska implementera Comparable (om man inte använder konstrukton med en parametar av typen Comparator.) I exemplet har nycklarna typen String där är ovanstående redan fixat. Datavetenskap (LTH) Föreläsning 10 VT 2020 62 / 65

Interfacet Map.Entry 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 10 VT 2020 63 / 65

Exempel på användning av klassen TreeMap Forts. 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. Det finns också en metod keyset som returnerar en mängd med nycklarna. Datavetenskap (LTH) Föreläsning 10 VT 2020 64 / 65

Exempel på vad du ska kunna Förklara begreppet binära sökträd. Förklara hur insättning, sökning och borttagning går till i ett binärt sökträd. Implementera binära sökträd med metoder för sökning och insättning. Känna till och kunna implementera interfacet Comparable. Kunna skicka med lambdauttryck som argument till parametrar av typen Comparator. Förklara begreppet balanserat binärt sökträd och varför man vill ha balanserade träd. Förklara begreppet AVL-träd. Ange tidskomplexitet för operationer på binära sökträd. Förklara vad de abstrakta datatyperna set och map är och vilka operationer man förväntas kunna utföra på dem. Använda Javas interface Set och Map samt klasserna TreeSet och TreeMap. Datavetenskap (LTH) Föreläsning 10 VT 2020 65 / 65