1 Implementering af fundamentale datastrukturer. 2 Stakke og køer Array-repræsentation Liste-repræsentation Hægtede lister Træer Terminologi Traversering.

Slides:



Advertisements
Lignende præsentationer
Den danske befolknings syn på handicappedes rettigheder
Advertisements

Atomer Et programmeret forløb. En måde at lære på.
Algoritmer og Datastrukturer 1 Amortiseret Analyse [CLRS, kapitel 17] Gerth Stølting Brodal.
Bolig selskabernes Landsforening– Almene lejeboliger - Maj/Juni Almene lejeboliger - Danmarkspanelet - Maj/Juni 2010.
1 Rekursion og algoritmedesign. 2 Rekursion Rekursiv definition af X: X defineres i termer af sig selv. Rekursion er nyttig, når en generel version af.
Datastrukturer Simple-type structs
Selve objektet versus referencen til objektet Nedarvning
Representations for Path Finding in Planar Environments.
Hvordan man skriver koden.
1 UNION-FIND. 2 inddata: en følge af heltalspar (p, q); betydning: p er “forbundet med” q uddata: intet, hvis p og q er forbundet, ellers (p, q) Eksempel.
1 Powerpointserie om In-line færdiggørelse ved Heatsettrykning Avisrotation Magasindybtryk Den Grafiske Højskole.
Induktion og rekursion
GP12, Martin Lillholm 1 Grundlæggende Programmering (GP) Efterår 2005 Forelæsning 12 Slides ligger på nettet. Du er velkommen til at printe dem nu. Vi.
Algoritmer og Datastrukturer 1 Binære Søgetræer [CLRS, kapitel 12] Gerth Stølting Brodal.
Begreber og Redskaber 9. Plan for idag I dag: Datastrukturer Tabeller Lister, mængder, maps, grafer Hægtede lister.
Datastrukturer og Collections Rasmus D. Lehrmann DM
ETU 2008 | Elevtilfredshedsundersøgelse Erhvervsskolen Nordsjælland HTX (Teknisk Gymnasium) - Hillerød Baseret på 313 besvarelser.
1 Søgning I. 2 Plan Sekventiel søgning Binær søgning Binære søgetræer Balancerede binære søgetræer træer.
1 Sortering I elementære metoder. 2 Plan Terminologi Elementære metoder til sortering -sortering ved udvælgelse -sortering ved indsættelse -Shellsort.
Anvendelser I Leg og spil.
Begreber og Redskaber 2. Plan for idag Noget om bestanddelene i et programmeringssprog Syntaksbeskrivelse af java Næste gang: –Binære tal –Repræsentation.
Forelæsning 3.1 Collections Javas for-each løkke
Matematik B 1.
Claus Brabrand, ITU, Denmark Mar 10, 2009EFFECTIVE JAVA Effective Java Presentation Workshop Claus Brabrand [ ] ( “FÅP”: First-year Project.
1 Tråde 2 Plan Trådbegrebet Synkronisering Koordinering Eksempel: et flertrådet spil.
Grunde til at jeg elsker dig
1 Implementering af fundamentale datastrukturer. 2 Plan Stakke og køer Array-repræsentation Liste-repræsentation Hægtede lister Træer Terminologi Traversering.
1 Søgetræer. 2 Binære søgetræer Definition Operationer Balancerede binære søgetræer AVL-træer Rød-sort-træer (AA-træer) B-træer Plan.
Lektion 7 Læsestof: Kopier fra Caranno
Fundamentale datastrukturer
FEN KbP/seminar2: design11 Kontraktbaseret programmering Seminar 2 Klassedesign – grundprincipper Eksempler: Stack Dictionary.
Algoritmer og Datastrukturer 1
1 Grafalgoritmer I. 2 Plan Grafer - definition - anvendelser - terminologi - eksempler på grafproblemer Grafgennemgang - dybde-først-gennemgang - bredde-først-gennemgang.
1 Anvendelser III Grafer. 2 Terminologi Repræsentation Traversering Korteste vej Topologisk sortering Problemkompleksitet og afgørlighed Plan.
Grafalgoritmer II.
Algoritmer og Datastrukturer 1 Binære Søgetræer [CLRS, kapitel 12] Gerth Stølting Brodal.
1 Sortering. 2 Sortering ved fletning (merge-sort) 7 2 | 9 4  | 2  2 79 | 4   72  29  94  4.
10. Datastrukturer. 2 Nordjyllands Erhvervakademi Collections library Datastrukturer i.NET kaldes normalt Collections Findes i namespace System.Collections.
1 Fundamentale datastrukturer. 2 Definitioner: abstrakt datatype, datastruktur Elementære datastrukturer og abstrakte datatyper: arrays, stakke, køer,
1 Fundamentale datastrukturer. 2 Definitioner: abstrakt datatype, datastruktur Elementære datastrukturer og abstrakte datatyper : arrays, stakke, køer,
Comparable Students German Students Composite Pattern State Pattern Observer Pattern Collections Interfaces Abstrakte klasser Design Patterns.
Begreber og Redskaber 7. Plan for idag Rekursive underprogrammer Rekursive datastrukturer Rekursion vs iteration Rekursivt: Flette sortering.
FEN KbP/seminar2: design21 Kontraktbaseret programmering Seminar 2 Klassedesign: Immutable lister Queue Shallowcopy og alkvantoren.
Algoritmer og Datastrukturer 1 Binære Søgetræer [CLRS, kapitel 12] Gerth Stølting Brodal Aarhus Universitet.
8 RÅD VEDRØRENDE GOD PROGRAMMERING Effective (brown) Java.
11 - Exceptions. 2 NOEA2009Java-kursus – Exceptions Hvad er en exception? En undtagelse. Typisk en fejl der opstår runtime Afbryder det normale programflow.
1 Anvendelser III Grafer. 2 Terminologi Repræsentation Traversering af grafer Korteste vej Topologisk sortering Problemkompleksitet og afgørlighed Plan.
KF04 GRAY Item 2, 12, 22, 32, 42, 52. Consider a builder when faced with many constructor parameters Item 2.
Anvendelser I Leg og spil.
03 – Udtryk og metoder. 2 NOEA2009Java-kursus – Udtryk og metoder Udtryk i Java Java har standard udtrykene… Værditildeling Subrutiner og funktionskald.
9. Interfaces. 2 Nordjyllands Erhvervakademi Objectives “Good class design starts with good application design — how many classes, do they relate.
Begreber og Redskaber 11. Plan for idag Lidt afrunding: Collections Framework i Java Noget om oversættere og sprog Evaluering Sidste gang øvelser før.
Paradigmer i Programmering 3. Højere ordens funktioner Idag: Højere ordens funktioner Algebraiske datatyper Næste gang: I/O, Filer, interaktive programmer.
Effective Java Blå gruppe. Item 18: Interfaces frem for abstrakte klasser Kan implementeres i klasser der ikke nedarver Eksisterende klasser kan nemt.
Begreber og Redskaber 4. Plan for idag Om metoder, parametre, returværdier Et par ord om objekt-orientering Håndkøring af programmer.
Begreber og Redskaber 3. Plan for idag Om metoder, parametre, returværdier Overblik over klasser,objekter,nedarvning Et par ord om objekt-orientering.
I o p o DAIMI, AU, November 1999Programkonstruktion I9E.1 Konstruktion og brug af klasser – en stak og en HP-regnemaskine push pop.
 Michael E. Caspersen, 2000Introducerende objektorienteret programmering6A.1 Programmering med interfaces – en stak og en HP-regnemaskine push pop.
Programmering med interfaces Separering af specifikation, anvendelse og implementation.
Programmering med interfaces – en stak og en HP-regnemaskine push pop.
Algoritmer og Datastrukturer 1 Amortiseret Analyse [CLRS, kapitel 17] Gerth Stølting Brodal.
Algoritmer og Datastrukturer 1 Elementære Datastrukturer [CLRS, kapitel 10] Gerth Stølting Brodal Aarhus Universitet.
Programmering med interfaces – en stak og en HP-regnemaskine push pop.
Containerklasser – klassifikation og brug.  Michael E. Caspersen, 2003IOOPContainerklasser.2 Mange objekter Containerklasser –antag at man skal repræsentere.
Algoritmer og Datastrukturer 1 Amortiseret Analyse [CLRS, kapitel 17]
Algoritmer og Datastrukturer 1
Algoritmer og Datastrukturer 1
Algoritmer og Datastrukturer 1
Algoritmer og Datastrukturer 1 Amortiseret Analyse [CLRS, kapitel 17]
Grundlæggende Algoritmer og Datastrukturer
Præsentationens transcript:

1 Implementering af fundamentale datastrukturer

2 Stakke og køer Array-repræsentation Liste-repræsentation Hægtede lister Træer Terminologi Traversering Plan

3 En stak (LIFO = LastInFirstOut) Stak poppush En stak er en sekvens af dataelementer af samme type, som muliggør følgende to operationer: push(x): Læg dataelementet x øverst på stakken (dvs. i begyndelsen af stakken) pop: Fjern det øverste element på stakken Kun stakkens øverste element ( top ) er tilgængeligt

4 En stak er en abstrakt datatype public interface Stack { void push(Object x); void pop() throws Underflow; Object top() throws Underflow; Object topAndPop() throws Underflow; boolean isEmpty(); void makeEmpty(); } package DataStructures; import Exceptions.*;

5 Implementering af en stak ved brug af et array topOfStack = 2 Object -instanser theArray

6 Implementering uden fejlhåndtering public class StackAr implements Stack { private Object[] theArray; private int topOfStack; static final int DEFAULT_CAPACITY = 10; public StackAr() { theArray = new Object[DEFAULT_CAPACITY]; topOfStack = -1; } public void push(Object x) { theArray[++topOfStack] = x; } public void pop() { topOfStack--; } public Object top() { return theArray[topOfStack]; } public Object topAndPop() { return theArray[topOfStack--]; } public boolean isEmpty() { return topOfStack == -1; } void makeEmpty() { topOfStack = -1; } }

7 Fejlhåndtering if (isEmpty()) throw new Underflow ("... "); Metoderne pop, top og topAndPop skal reagere fornuftigt, hvis de bliver kaldt, når stakken er tom. Vi vælger at lade dem kaste undtagelsen Underflow i dette tilfælde. I begyndelsen af hver af de tre metoder indsættes

8 Array-udvidelse Hvis arrayet er fyldt, når push kaldes, fordobles dets størrelse. public void push(Object x) { if (topOfStack + 1 == theArray.length) doubleArray(); theArray[++topOfStack] = x; } private void doubleArray() { Object[] newArray = new Object[theArray.length * 2]; for (int i = 0; i < theArray.length; i++) newArray[i] = theArray[i]; theArray = newArray; } Alternativt kunne kopieringen ske således: System.arraycopy(theArray, 0, newArray, 0, theArray.length);

9 Amortiseret køretid Fordobling af arrayet er kostbar i tid: O(N). Fordobling er imidlertid en relativt sjældent forekommende foreteelse. En fordobling, der involverer N elementer, må nemlig være forårsaget af mindst N/2 kald af push. Vi kan fordele omkostningen O(N) for fordoblingen på hvert af de N/2 push -operationer. Derved bliver omkostningen for hvert push kun multipliceret med en konstant faktor. I det “lange løb” er køretiden for såvel push som pop O(1).

10 Implementering af en stak ved brug af en hægtet liste topOfStack class ListNode { ListNode(Object e, ListNode n) { element = e; next = n; } Object element; ListNode next; } ListNode

11 Implementering uden fejlhåndtering public class StackLi implements Stack { private ListNode topOfStack; public StackLi() { makeEmpty(); } public void push(Object x) { topOfStack = new ListNode(x, topOfStack); } public void pop() { topOfStack = topOfStack.next; } public Object top() { return topOfStack.element; } public Object topAndPop() { Object t = top(); pop(); return t; } public boolean isEmpty() { return topOfStack == null; } void makeEmpty() { topOfStack = null; } }

12 En kø (FIFO = FirstInFirstOut) En kø er en sekvens af dataelementer af samme type, som muliggør følgende to operationer: enqueue(x): Sæt dataelementet x bagest i køen dequeue: Fjern det første element fra køen dequeue enqueue Kø

13 En kø er en abstrakt datatype public interface Queue { void enqueue(Object x); Object dequeue() throws Underflow; Object getFront() throws Underflow; boolean isEmpty(); void makeEmpty(); } package DataStructures; import Exceptions.*;

14 Implementering af en kø ved brug af en hægtet liste class ListNode { ListNode(Object e, ListNode n) { element = e; next = n; } Object element; ListNode next; } frontback ListNode

15 Implementering uden fejlhåndtering public class QueueLi implements Queue { private ListNode front, back; public QueueLi() { makeEmpty(); } public void enqueue(Object x) { if (isEmpty()) front = back = new ListNode(x, null); else back = back.next = new ListNode(x, null); } public Object dequeue() { Object t = front.element; front = front.next; return t; } public Object getFront() { return front.element; } public boolean isEmpty() { return front == null; } public void makeEmpty() { front = back = null; } }

16 Implementering af en kø ved brug af et array Undgå flytning af arrayelementer ved enqueue og dequeue back = front = 0

17 back = front = 2currentSize = 4 Cirkulær buffer dequeue : back = front = 3currentSize = 3

18 enqueue : back = front = 3currentSize = 4 enqueue med “wraparound” back = front = 3currentSize = 6

19 Implementering uden fejlhåndtering public class QueueAr implements Queue { private Object[] theArray; private int front, back, currentSize; private static final int DEFAULT_CAPACITY = 10; public QueueAr() { theArray = new Object[DEFAULT_CAPACITY]; makeEmpty(); } public void enqueue(Object x) { back = (back + 1) % theArray.length; theArray[back] = x; currentSize++; } public Object dequeue() { Object t = theArray[front]; front = (front + 1) % theArray.length; currentSize--; return t; } public Object getFront() { return theArray[front]; } public boolean isEmpty() { return currentSize == 0; } void makeEmpty() { back = -1; front = 0; currentSize = 0; } }

20 Array-udvidelse Hvis arrayet er fyldt, når equeue kaldes, fordobles dets størrelse. public void equeue(Object x) { if (currentSize == theArray.length) doubleQueue(); back = (back + 1) % theArray.length; currentSize++; theArray[back] = x; } private void doubleQueue() { Object[] newArray = new Object[theArray.length * 2]; for (int i = 0; i < currentSize; i++, front = (front + 1) % theArray.length) newArray[i] = theArray[front]; theArray = newArray; front = 0; back = currentSize - 1; }

21 En hægtet liste class ListNode { ListNode(Object e, ListNode n) { element = e; next = n; } Object element; ListNode next; } frontOfList ListNode

22 Indsættelse og sletning current.next = new ListNode(x, current.next); Indsættelse af nyt element x efter current : Sletning af elementet efter current : current.next = current.next.next; current

23 header Brug af en header-knude forenkler indsættelse og sletning forrest i listen public class LinkedList implements List { public LinkedList() { header = new ListNode(null, null); } public boolean isEmpty() { header.next == null; } public void makeEmpty() { header.next = null; } ListNode header; }

24 Iteratorer En iterator er et objekt, der benyttes til at gennemløbe elementerne i en datastruktur, uden at anvenderen behøver at kende til den konkrete implementering af datastrukturen. Fordele: (1) understøtter dataabstraktion (2) sikrer mod fejl og misbrug

25 En iterator til gennemløb af hægtede lister public interface ListItr { void first(); boolean isInList(); void advance(); Object retrieve(); void zeroth(); void insert(Object x) throws ItemNotFound; boolean find(Object x); void remove(Object x) throws ItemNotFound; } public class LinkedListItr implements ListItr { private LinkedList theList; private ListNode current;... }

26 Eksempel på anvendelse af LinkedListItr static public void print(LinkedList list) { if (list.isEmpty()) System.out.print("Empty list"); LinkedListItr itr = new LinkedListItr(list); for (itr.first(); itr.isInList(); itr.advance()) System.out.print(retrieve() + " "); System.out.println(); }

27 Implementation af LinkedListItr public class ListItr { private LinkedList theList; private ListNode current; public ListItr(LinkedList list) { theList = list; current = theList.header.next; } public void first() { current = theList.header.next; } public boolean isInList() { return current != null && current != theList.header; } public void advance() { if current != null) current = current.next; } public Object retrieve() { return isInList() ? current.element : null; } public void zeroth() { current = theList.header; } public void insert(Object x) throws ItemNotFound {...} public boolean find(Object x) {...} public void remove(Object x) throws ItemNotFound {...} }

28 public void insert(Object x) throws ItemNotFound { if (current == null) throw new ItemNotFound("insertion error"); else current = current.next = new ListNode(x, current.next); } public boolean find(Object x) { ListNode n = theList.header.next; while (n != null && !n.element.equals(x)) n = n.next; if (n == null) return false; current = n; return true; }

29 public void remove(Object x) throws ItemNotFound { ListNode n = theList.header; while (n.next != null && !n.next.element.equals(x)) n = n.next; if (n.next == null) throw new ItemNotFound("remove fails"); n.next = n.next.next; current = theList.header; }

30 Træer

31 Et træ er en samling af knuder og kanter, (V, E), som opfylder visse krav: En knude, v, er et simpelt dataobjekt, der kan have et navn og en tilknyttet information. En af knuderne er udpeget som rod i træet. En kant, (v 1,v 2 ), er en forbindelse imellem to knuder, v 1 og v 2. En vej er en liste af knuder, (v 1,v 2,...,v k ), hvor alle successive knuder, v i og v i+1, er indbyrdes forbundne (dvs. tilhører E). For at udgøre et træ skal der mellem roden og enhver anden knude findes præcis én vej. Træer

32 Terminologi Rod: R X er far til Y Y er søn til X (Y er barn af X) U, V og W er børn af T S er bedstefar til Z S er forgænger til Y (S er over Y) Y er efterkommer af S (Y er under S) Terminale knuder (blade): Y, Z, U, V, W Ikke-terminale knuder: R, S, X, T Rod R S X Y Z T U VW Terminal (blad) Ikke-terminal Niveau 0 Niveau 1 Niveau 2 Niveau 3

33 Terminologi (fortsat) Et træ kaldes ordnet, hvis rækkefølgen af sønnerne for enhver knude er specificeret. En knudes niveau er antallet af knuder på vejen fra knuden til roden (minus knuden selv). Et træs højde er det maksimale niveau for alle knuder i træet.

34 Binære træer Rekursiv definition: Et binært træ er enten et tomt træ, eller en knude, som har et venstre og et højre binært undertræ. Et binært træ er et ordnet træ, hvor hver knude har højst 2 sønner.

35 Klassen BinaryNode class BinaryNode { BinaryNode left,right; Object element; BinaryNode(Object e, BinaryNode lt, BinaryNode rt) { element = e; left = lt; right = rt; } static BinaryNode duplicate(BinaryNode t) {...} static int size(BinaryNode t) {...} static int height(BinaryNode t) {...} static void preOrderPrint(BinaryNode t) {...} static void inOrderPrint(BinaryNode t) {...} static void postOrderPrint(BinaryNode t) {...} }

36 Klassen BinaryTree class BinaryTree { BinaryNode root; BinaryTree() { root = null; } void duplicate(BinaryTree rhs) { if (this != rhs) root = rhs.duplicate(root); } int size() { return BinaryNode.size(root); } int height() { return BinaryNode.height(root); } void preOrderPrint() { BinaryNode.preOrderPrint(root); }void inOrderPrint() { BinaryNode.inOrderPrint(root); }void postOrderPrint() { BinaryNode.postOrderPrint(root); } }

37 Brug af rekursion static BinaryNode duplicate(BinaryNode t) { return t == null ? null : new BinaryNode(t.element, duplicate(t.left), duplicate(t.right); } static int size(BinaryNode t) { return t == null ? 0 : 1 + size(t.left) + size(t.right); } static int height(BinaryNode t) { return t == null ? -1 : 1 + Math.max(height(t.left), height(t.right)); }

38 (1) Preorder: Besøg roden. Besøg venstre undertræ. Besøg højre undertræ. Traversering af binære træer (besøg alle knuder) P M S A B L G R E F T (2) Inorder: Besøg venstre undertræ. Besøg roden. Besøg højre undertræ. (3) Postorder: Besøg venstre undertræ. Besøg højre undertræ. Besøg roden. PMSABLGRTEF ASBMPLGTRFE ABSMTFERGLP

39 Inorder: void inOrderPrint(BinaryNode t) { if (t != null) { inOrderPrint(t.left); System.out.printl(t.element); inOrderPrint(t.right); } Preorder: void preOrderPrint(BinaryNode t) { if (t != null) { System.out.printl(t.element); preOrderPrint(t.left); preOrderPrint(t.right); } } Postorder: void postOrderPrint(BinaryNode t) { if (t != null) { postOrderPrint(t.left); postOrderPrint(t.right); System.out.printl(t.element); } Traversering ved hjælp af rekursion

40 Traversering ved brug af iterator abstract public class TreeIterator { BinaryTree t: BinaryNode current; public TreeIterator(BinaryTree t) { this.t = t; current = null; } abstract public void first(); abstract public void advance(); public final boolean isValid() { current != null; } public final Object retrieve() throws ItemNotFound { if (current == null) throw new ItemNotFound("TreeIterator retrieve"); return current.element; } }

41 Traversering ved hjælp af en stak Traverseringstypen er bestemt af antallet af gange et BinaryNode - objekt “poppes” fra stakken: 3 gange: postorder 2 gange: inorder 1 gang: preorder class StNode { StNode(BinaryNode n) { node = n; } BinaryNode node; int timesPopped; }

42 Klassen PostOrder public class PostOrder extends TreeIterator { private Stack s; public PostOrder(BinaryTree t) { super(t); s = new StackAr(); s.push(new StNode(t.root)); } public void first() { s.makeEmpty(); if (t.root != null) s.push(new StNode(t.root)); try { advance(); } catch (ItemNotFound e) {} } public void advance() throws ItemNotFound {...} }

43 public void advance() throws ItemNotFound { if (s.isEmpty()) { if (current == null) throw new ItemNotFound("PostOrder advance"); current = null; return; } try { for (;;) { StNode cnode = (StNode) s.top(); switch (++cnode.timesPopped) { case 1: if (cnode.node.left != null) s.push(new StNode(cnode.node.left)); break; case 2: if (cnode.node.right != null) s.push(new StNode(cnode.node.right)); break; case 3: s.pop(); current = cnode.node; return; } } catch (Underflow e) {} } Metoden advance

44 Klassen InOrder public class InOrder extends PostOrder { public InOrder(BinaryTree t) { super(t); } public void advance() throws ItemNotFound { if (s.isEmpty()) { if (current == null) throw new ItemNotFound("InOrder advance"); current = null; return; } try { for (;;) { StNode cnode = (StNode) s.top(); switch (++cnode.timesPopped) { case 1: if (cnode.node.left != null) s.push(new StNode(cnode.node.left)); break; case 2: s.pop(); current = cnode.node; if (cnode.node.right != null) s.push(new StNode(cnode.node.right)); return; } } catch (Underflow e) {} }

45 public class PreOrder extends TreeIterator { private Stack s; public PreOrder(BinaryTree t) { super(t); s = new StackAr(); s.push(t.root); } public void first() { s.makeEmpty(); if (t.root != null) s.push(t.root); try { advance(); } catch (ItemNotFound e) {} } public void advance() throws ItemNotFound {...} } Klassen PreOrder Hjælpeklassen StNode kan undværes

46 public void advance() throws ItemNotFound { if (s.isEmpty()) { if (current == null) throw new ItemNotFound("PreOrder advance"); current = null; return; } try { current = s.topAndPop(); } catch (Underflow e) {} if (current.right != null) s.push(current.right); if (current.left != null) s.push(current.left); } Metoden advance Bemærk at current.right stakkes før current.left.

47 (4) Level-order: Besøg knuderne fra top til bund, i stigende niveauorden, startende i roden og fra venstre mod højre på hvert niveau. Niveau-traversering af træer P M S A B L G R E F T PMLSGABRTEF Niveau-traversering opnås ved i klassen Preorder at erstatte stakken med en kø. Bemærk at køen kan blive meget lang!Cirka N/2, hvor N er antallet af knuder i træet.

48 Traversering ved hjælp af korutiner En korutine er en rutine, der midlertidigt er i stand til at standse sin udførelse. I mellemtiden kan en anden korutine blive udført. En standset korutine kan senere genoptage sin udførelse. Denne form for programsekvensering kaldes for alternering. resume(b) resume(a) coroutine a coroutine b

49 Klassen Coroutine public class abstract Coroutine { protected abstract void body(); public static void resume(Coroutine c); public static void call(Coroutine c); public static void detach(); }

50 public class InOrderIterator extends TreeIterator { public InOrderIterator(BinaryTree t) { super(t); } void traverse(BinaryNode t) { if (t != null) { traverse(t.left); current = t; detach(); traverse(t.right); } else current = null; } Rekursiv inorder-traversering ved hjælp af koroutinesekvensering

51 public abstract class TreeIterator extends Coroutine { BinaryTree t; BinaryNode current; public TreeIterator(BinaryTree theTree) { t = theTree; current = null; call(this); } abstract void traverse(BinaryNode t) {...} protected void body() { traverse(t.root); } public boolean isValid() { return current != null; } public void advance() throws ItemNotFound { if (current == null) throw new ItemNotFound("TreeIterator advance"); call(this); } public Object retrieve() throws ItemNotFound { if (current == null) throw new ItemNotFound("TreeIterator retrieve"); return current.element; }

52 public class InOrderTest { public static void main(String[] args) { BinarySearchTree t = new BinarySearchTree(); try { t.insert(new MyInteger(4)); t.insert(new MyInteger(2)); t.insert(new MyInteger(6)); t.insert(new MyInteger(1)); t.insert(new MyInteger(3)); t.insert(new MyInteger(5)); t.insert(new MyInteger(7)); } catch(Exception e) {} InOrderIterator itr = new InOrderIterator(t); try { for ( ; itr.isValid(); itr.advance()) System.out.print(" " + itr.retrieve()); System.out.println(); } catch (ItemNotFound e) {} } Et testprogram Udskrift:

53 Designmønstre Designmønster: En model for samspillet imellem objekter, der indfanger nyttige strukturer ved løsning af en række problemer Eksempler: Container: udgør en beholder for en mængde af objekter. Iterator: giver sekventiel tilgang til objekterne i en container, uden at dennes interne repræsentation afsløres for klienten. Adapter:tilpasser grænsefladen for en klasse til bestemte forventninger hos en klient. Visitor: repræsenterer en operation, der skal udføres på objekterne i en container.

54 Visitor-designmønsteret interface Visitor {) void visit(Object obj); boolean isDone(); } class Container { void accept(Visitor v) { for each object obj in this container { if (!v.isDone()) return; v.visit(obj); }

55 Eksempel på en visitor class PrintingVisitor implements Visitor { public void visit(Object obj) { System.out.println(obj); } public boolean isDone() { return false; }

56 Rekursiv dybde-først-traversering ved hjælp af en visitor interface TreeVisitor { void preVisit(Object obj); void inVisit(Object obj); void postVisit(Object obj); boolean isDone(); } public class BinaryTree { BinaryNode root;... public void depthFirstTraversal(TreeVisitor v) { if (root != null) root.depthFirstTraversal(v); }

57 class BinaryNode { BinaryNode left, right; Object element;... void depthFirstTraversal(TreeVisitor v) { v.preVisit(element); if (left != null) left.depthFirstTraversal(v); v.inVisit(element); if (right != null) right.depthFirstTraversal(v); v.postVisit(element); } Rekursiv dybde-først-traversering i klassen BinaryNode

58 abstract class TreeVisitorAdapter implements TreeVisitor { void preVisit(Object obj) {} void inVisit(Object obj) {} void postVisit(Object obj) {} boolean isDone() { return false; } } public class InOrder extends TreeVisitorAdapter { private Visitor visitor; public InOrder(Visitor v) { visitor = v; } public void inVisit(Object obj) { visitor.visit(obj); } public boolean isDone() { return visitor.isDone(); } } Visitor for inorder-traversering

59 BinaryTree t = new BinaryTree();... t.depthFirstTraversal(new InOrder(new PrintingVisitor())); Eksempel på anvendelse

60 Læs kapitel 18 i lærebogen (side ) Løs følgende opgaver 8-1. Opgave Opgave Opgave Opgave Opgave Opgave Opgave Opgave Opgave 17.9 Ugeseddel oktober - 6. november