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



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

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

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 9 Innehåll

Föreläsning 9 Innehåll

Föreläsning 9 Datastrukturer (DAT037)

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

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

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

Föreläsning Datastrukturer (DAT036)

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

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

Föreläsning 2. Länkad lista och iterator

Föreläsning 6: Introduktion av listor

Föreläsning 13 och 14: Binära träd

OOP Objekt-orienterad programmering

Föreläsning 2. Länkad lista och iterator

Algoritmer och datastrukturer

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

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

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

6 Rekursion. 6.1 Rekursionens fyra principer. 6.2 Några vanliga användningsområden för rekursion. Problem löses genom:

Lösningsförslag till tentamen Datastrukturer, DAT037,

Föreläsning 10 Datastrukturer (DAT037)

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

Lösningsförslag till exempeltenta 1

Dugga Datastrukturer (DAT036)

Tentamen Programmeringsteknik II Inledning. Anmälningskod:

13 Prioritetsköer, heapar

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

Tentamen TEN1 HI

Föreläsning 3. Stack

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

Sätt att skriva ut binärträd

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

Föreläsning 4 Datastrukturer (DAT037)

Tentamen OOP

4 13 / %.; 8 </" '': " / //&' " " ' * TelefonKostnad +,-%&. #!" $% " &' . > / ' 5 /' * 13/ &' static Math 1+" &'/ % 12 "" static "' * 1 /") %& &

Objektsamlingar i Java

Tentamen Datastrukturer D DAT 036/DIT960

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

Tentamen, EDA501 Programmering M L TM W K V

Objektorienterad programmering D2

Tentamen i Objektorienterad programmering

Tentamen. 2D4135 vt 2005 Objektorienterad programmering, design och analys med Java Lördagen den 28 maj 2005 kl

BST implementering, huvudstruktur

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 9 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Objektorienterad programmering i Java

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.

Exempel på listor (klassen ArrayList). Ett exempel med fält. Avbildning är en speciell typ av lista HashMap.

Föreläsning 3. Stack

Algoritmer och datastrukturer 2012, föreläsning 6

Föreläsning 4. ADT Kö Kö JCF Kö implementerad med en cirkulär array Kö implementerad med en länkad lista Läsanvisningar och uppgifter

Lösningsförslag till tentamen i EDA011/EDA017 Programmeringsteknik för F, E, I, π och N 25 maj 2009

Tentamen. Programmeringsmetodik, KV: Java och OOP. 17 januari 2004

Lösningsförslag till tentamen Datastrukturer, DAT037 (DAT036), Tiden det tar att utföra en iteration av loopen är oberoende av värdet på

Tentamen DE12, IMIT12, SYST12, ITEK11 (även öppen för övriga)

Föreläsning 4. ADT Kö Kö JCF Kö implementerad med en cirkulär array Kö implementerad med en länkad lista

Tentamen Datastrukturer, DAT037 (DAT036)

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

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

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

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

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

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

Tentamen på kursen DA7351, Programmering , kl Malmö högskola Teknik och samhälle. DA7351, Programmering

DAI2 (TIDAL) + I2 (TKIEK)

Träd. Ett träd kan se ut på detta sätt:

TENTAMEN PROGRAMMERINGSMETODIK MOMENT 2 - JAVA, 4P

Tentamen TEN1 HI

Tentamen, EDAA20/EDA501 Programmering

Tentamen TEN1 HI

Föreläsning 5 Datastrukturer (DAT037)

Föreläsning 10. ADT:er och datastrukturer

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

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

Föreläsning 6. Rekursion och backtracking

Algoritmanalys. Genomsnittligen behövs n/2 jämförelser vilket är proportionellt mot n, vi säger att vi har en O(n) algoritm.

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, EDA501 Programmering M L TM W K V

Tentamen Datastrukturer (DAT036/DAT037/DIT960)

Trädstrukturer och grafer

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 6. Rekursion och backtracking

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

Föreläsning 4: Kombinatorisk sökning

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

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

trafiksimulering Intro OU5 trafiksimulering

Kungliga Tekniska Högskolan Ämneskod 2D4134 Nada Tentamensdag aug - 23 Tentamen i Objektorientering och Java Skrivtid 5 h

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

Lösningsförslag till tentamen i EDA011/EDA017 Programmeringsteknik för F, E, I, π och N 27 maj 2008

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

Föreläsning 3 Datastrukturer (DAT037)

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

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

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

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

Transkript:

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

Föreläsning 7 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 Läsanvisningar och uppgifter Jag kommer inte i närheten av att hinna ta upp allt på föreläsningen så det är oerhört viktigt att ni också läser boken.

nivå 1 Terminologi - träd nivå 2 nivå 3 nivå 4 Ett träd i datalogi består av en rotnod och ett ändligt antal underträd (subtrees). Trädets höjd är antalet nivåer. Ett träd är en graf där man kan ta sig mellan två noder på endast ett sätt. N noder ger N-1 bågar. Vi kommer främst titta på binära träd.

Binära träd Ett binärt träd är ett träd där varje nod har maximalt 2 barn Definition: Ett binärt träd är antingen tomt eller så har rotnoden 2 underträd (subtree) som också är binära träd (vänster och höger underträd).

Binärt sökträd (BST) Ett binärt sökträd är ett binärt träd som är ordnat efter nodernas nycklar. Definition: Ett binärt sökträd är antingen tomt eller så har rotnoden två subträd som också är binära sökträd. Alla nycklar i det vänstra subträdet är mindre än rotnodens nyckel och alla nycklar i det högra subträdet är större än rotnodens nyckel. Definitionen ger att varje nyckel är unik. Vi kan inte ha dubbletter i ett binärt sökträd.

Poäng Att söka i ett binärt sökträd är O(log(n)) om det är komplett (balanserat). Att sätta in i ett binärt sökträd är O(1) när vi hittat platsen. Vi behöver aldrig flytta några länkar. Vi bara hänger på lövet där det passar. Att söka i en sorterad array är också O(log(n)) men att sätta in är O(n) (vi måste flytta i snitt n/2 element). Detsamma gäller när vi tar bort element. I en länkad lista är insättning och borttagning O(1) men där är binär sökning inte rimligt eftersom det är O(n) att hitta ett specifikt element.

Självbalanserande binära sökträd När vi sätter in nya element i trädet är det bara följa trädet ner. Bygg upp ett träd genom att sätta in elementen: 10, 5, 7, 15, 12, 1, 20 Om man sätter in element med nycklarna 1,2,3,4,5 i den ordningen får man istället ett binärt sökträd som egentligen är en länkad lista och sökningen blir O(n). För att undvika dylikt finns självbalanserade träd som ser till att de är balanserade.

Traversera Att besöka alla noder i ett träd kallas att traversera trädet. Tre traverseringsordningar (rekursiva): Inorder. Besök först trädets vänstra del, sedan noden själv och sist trädets högra del. (1,2,3,4,5,6,7) Preorder. Besök först noden själv, sedan trädets vänstra del och sist trädets högra del. (4,2,1,3,6,5,7) Postorder. Besök först trädets vänstra del, sedan trädets högra del och sist noden själv. (1,3,2,5,7,6,4) Normalt använder vi inorder.

Binärt sökträd (JCF) TreeMap implementerar ett Red-Black Tree vilket är ett självbalanserande binärt sökträd som inte är perfekt balanserat men O(log(n)) är garanterat. Vi hinner inte titta på detta i denna kurs utan ska fokusera på att förstå hur ett binärt sökträd implementeras.

ADT Binärt sökträd? En ADT för ett träd innehåller typiskt funktioner som relaterar till trädstrukturen (som används tex för ett filträd) men ett binärt sökträd används normalt som en implementering av en datastruktur där vi vill kunna söka, sätta in och ta ut effektivt. Vi väljer här att tillhandahåller typiska operationer såsom add, delete och find som publika. Själva trädmetoderna blir interna privata metoder. Användaren av listan behöver alltså inte bry sig om att vår inre struktur är ett binärt sökträd.

Implementering av ett binärt sökträd public class BinarySearchTree<E extends Comparable<E>> { private static class Node<E>{ private E data; private Node<E> left,right; private Node(E d){ data=d; left=right=null; @Override public String tostring(){ return data.tostring(); private Node<E> root; public BinarySearchTree(){ root=null;

E extends Comparable<E> Datat vi stoppar in måste gå att ordna. E extends Comparable<E> gör att vi kan vara säkra på att E går att jämföra med E Klasser såsom String, Integer implementerar Comparable Oftast vill man sortera enligt en nyckel som endast är en del av datat. Ex: public class PhoneEntry implements Comparable<PhoneEntry>{ public String firstname, lastname, number; public PhoneEntry(String f, String l, String n){ firstname=f; lastname=l; number=n; @Override public int compareto(phoneentry e){ if(lastname.compareto(e.lastname)==0) return firstname.compareto(e.firstname); else return lastname.compareto(e.lastname); @Override public String tostring(){ return firstname.tostring()+" "+lastname.tostring()+" "+number.tostring();

Traversera trädet inorder private void inorder(node<e> node, StringBuilder sb){ if(node!=null){ inorder(node.left, sb); sb.append(": "+node.tostring()); inorder(node.right, sb); public String tostring(){ StringBuilder sb = new StringBuilder(); inorder(root,sb); return sb.tostring();

add private boolean add(e data,node<e> node){ if(data.compareto(node.data)==0) return false; else if(data.compareto(node.data)<0) if(node.left==null){ node.left = new Node<E>(data); return true; else return add(data,node.left); else if(node.right==null){ node.right = new Node<E>(data); return true; else return add(data,node.right); public boolean add(e data){ if(root==null){ root = new Node<E>(data); return true; else return add(data,root);

find private E find(e target, Node<E> node){ if( node==null) return null; if(target.compareto(node.data)==0) return node.data; if(target.compareto(node.data)<0) return find(target,node.left); return find(target,node.right); public E find(e target){ return find(target, root);

Exempel BinarySearchTree<PhoneEntry> bst= new BinarySearchTree<PhoneEntry>(); while(true){ String fname = JOptionPane.showInputDialog("Förnamn:"); if(fname.equals("")) break; String lname = JOptionPane.showInputDialog("Efternamn:"); String number = JOptionPane.showInputDialog("Nummer:"); bst.add(new PhoneEntry(fName, lname, number)); while(true){ String fname = JOptionPane.showInputDialog("Förnamn:"); if(fname.equals("")) break; String lname = JOptionPane.showInputDialog("Efternamn:"); System.out.println(bst.find(new PhoneEntry(fName, lname, "")));

Ta bort Det finns tre fall att ta hänsyn till när vi tar bort en nod: noden är ett löv noden har bara ett subträd noden har både vänster och höger subträd Fall 1 är trivialt: vi sätter helt enkelt förälderns relevanta subträd till NULL

Noden har bara ett subträd Också relativt enkelt. Vi ersätter helt enkelt noden med dess barn. Ex: Vi ska ta bort 4: 8 8 4 9 9 6 6 5 7 5 7

Noden har både vänster och höger subträd Vi måste nu lösa vad vi ska göra med de två barnen. Lösningen är att vi ersätter noden med den minsta noden i det högra underträdet. Denna kan inte ha något vänsterbarn (den är ju minst) och är därmed lätt att ta bort (fall 2) Ex: vi vill ta bort nod B. H H B N C N A E A E C F F D D

implementering public E delete(e target){ root = delete(target,root); return deleteddata; Eftersom vi ska ändra subträdet som har noden vi ska ta bort som rot är det enklast att rekursivt leta upp rätt nod och i varje steg returnera det nya trädet. Dock behöver vår wrapper returnera datat från noden vi tar bort. Detta kunde vi då gjort genom att anropa find först och spara detta men det skulle innebära att vi letar upp noden två gånger. Bättre då att spara datat i en privat medlemsvariabel i klassen: private E deleteddata;

private Node<E> delete(e target,node<e> node){ if(node==null){//target finns ej i trädet deleteddata = null; return null; else{ if(target.compareto(node.data)<0){//target finns i vänstra trädet node.left=delete(target,node.left); //om det finns return node; else if(target.compareto(node.data)>0){//target i högra trädet node.right=delete(target,node.right); return node; else{//target finns i node!

deleteddata = node.data; //lagrar data att returnera //nu ska vi bygga om trädet if(node.left==null) //noden som ska bort saknar vänster träd return node.right; else if(node.right==null)//noden som ska bort saknar högerträd return node.left; else{//noden vi ska ta bort har två barn H B E B A N H N

Node<E> nodetomove=node.right, parentnodetomove=node; if(nodetomove.left==null){//högra barnet har inget vänsterbarn nodetomove.left=node.left; return nodetomove; //högra barnet har vänsterbarn while(nodetomove.left!=null){ parentnodetomove=nodetomove; nodetomove=nodetomove.left; parentnodetomove.left = nodetomove.right; node.data=nodetomove.data; return node; A B E H F N parentnodetomove nodetomove A B C E D H F N

Läsanvisningar och uppgifter KW 6.1, 6.2, 6.3, 6.4 Uppgifter: NB 26, 27, 28 (1p), 29 (2p), 30 (2p)

Uppgifter Utgå från föreläsningens implementering av ett binärt sökträd när du löser nedanstående uppgifter. Skriv också testkod till alla som ger poäng. NB 26 Skriv en main som läser in sju ord från användaren och placerar dessa i ett BST. Kör programmet och skriv in 7 ord så att trädet får minsta möjliga höjd. Kör programmet och skriv in 7 ord så att trädet får maximal höjd. NB 27 Skriv funktioner som traverserar trädet med preorder och postorder. NB 28 (1p) Skriv två funktioner numberofleaves och numberofnodes till vår implementation från föreläsningen. NB 29 (2p) Skriv om sökfunktionen så att den är iterativ istället för rekursiv. NB 30 (2p) Skriv en funktion maximum som returnerar det största värdet i ett binärt sökträd. Skriv en rekursiv och en iterativ version.