1 Implementering af fundamentale datastrukturer. 2 Plan 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å.
Velkommen til Softwarekonstruktion
Bolig selskabernes Landsforening– Almene lejeboliger - Maj/Juni Almene lejeboliger - Danmarkspanelet - Maj/Juni 2010.
1 Frameworks. 2 Plan Frameworks • Kollektioner • Input/output Nyt designmønster: Decorator.
Array og ArrayList Et slideshow. Som er sødt.. Hvordan virker ArrayList?  ArrayList NAVN = new ArrayList ();  NAVN.add(”Værdi”);  NAVN.add(index, ”værdi”)
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.
KONCEPT Klasser og objekter En klasse beskriver et World ArrayList
Datastrukturer og Collections Oversigt og forskel imellem Jave og.net Collections library Collection interfaces ArrayList IList interface Hashtable Hashtable.
Datastrukturer Simple-type structs
Array vs. ArrayList. Arrays Et array er en struktureret metode til at gemme flere værdier af den samme datatype. Data’en i et array ligger op ad hinanden.
Representations for Path Finding in Planar Environments.
HUSKESPIL – den lille tabel
Titel: Arial, fed, skriftstr. 20, mørkegrå. Tekst: Arial, normal, fed eller kursiv, skriftstr. 10, 12 og 14 til print – 16 og 18 til projektor – mørkegrå.
 2 3  3 =  83  43  53  63  73  93  10 4.
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.
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.
Region Midtjyllands tilbud 2013
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.
Begreber og Redskaber 5. Collections i Java 1.2 Framework: samling af datastrukturer og algoritmer som generelt værktøj. En ramme til at arbejde med søgning.
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.
Anvendelser I Leg og spil.
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 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 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.
1 Kap. 4, Jordens Tyngdefelt = Torge, 2001, Kap. 3. Tyngdekraftens retning og størrelse g (m/s 2 ) Acceleration Tyngdepotentialet (W): evene til at udføre.
FEN KbP/seminar2: design21 Kontraktbaseret programmering Seminar 2 Klassedesign: Immutable lister Queue Shallowcopy og alkvantoren.
1 Anvendelser III Grafer. 2 Terminologi Repræsentation Traversering af grafer Korteste vej Topologisk sortering Problemkompleksitet og afgørlighed Plan.
Nedarvning.
1 Implementering af fundamentale datastrukturer. 2 Stakke og køer Array-repræsentation Liste-repræsentation Hægtede lister Træer Terminologi Traversering.
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.
Forelæsning 7.1 – repetition
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.
Collectionklasser Klassifikation og anvendelse. dIntProg, F08Collectionklasser.2 Samlinger af objekter Objektreferencer –for at holde fast i et objekt.
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
Algoritmer og Datastrukturer 1
Algoritmer og Datastrukturer 1
Grundlæggende Algoritmer og Datastrukturer
Præsentationens transcript:

1 Implementering af fundamentale datastrukturer

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

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(); Object top(); Object topAndPop(); boolean isEmpty(); void makeEmpty(); } package weiss.nonstandard;

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

6 Implementering uden fejlhåndtering public class ArrayStack implements Stack { private Object[] theArray; private int topOfStack; private static final int DEFAULT_CAPACITY = 10; public ArrayStack() { 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 EmptyStackException(); 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 EmptyStackException 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 push O(1). Amortisering: regelmæssig tilbagebetaling af lån.

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 ListStack implements Stack { private ListNode topOfStack; public ListStack() { 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(); Object getFront(); boolean isEmpty(); void makeEmpty(); } package weiss.nonstandard;

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 ListQueue implements Queue { private ListNode front, back; public ListQueue() { 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 ArrayQueue implements Queue { private Object[] theArray; private int front, back, currentSize; private static final int DEFAULT_CAPACITY = 10; public ArrayQueue() { theArray = new Object[DEFAULT_CAPACITY]; makeEmpty(); } public void makeEmpty() { back = -1; front = 0; currentSize = 0; } 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; } }

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 Indsættelse af nyt element forrest i listen? Sletning af det forreste element?

23 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; } private ListNode header; } header

24 Træer

25 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

26 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

27 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.

28 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.

29 Klassen BinaryNode class BinaryNode { BinaryNode left, right; Object element; BinaryNode(Object e, BinaryNode lt, BinaryNode rt) { element = e; left = lt; right = rt; } }

30 Klassen BinaryTree public class BinaryTree { private BinaryNode root; public BinaryTree() { root = null; } public int size() { return size(root); }public int height() { return height(root); } public void preOrderPrint() { preOrderPrint(root); }public void inOrderPrint() { inOrderPrint(root); }public void postOrderPrint() { postOrderPrint(root); } private int size(BinaryNode t) {...}private int height(BinaryNode t) {...} private void preOrderPrint(BinaryNode t) {...}private void inOrderPrint(BinaryNode t) {...}private void postOrderPrint(BinaryNode t) {...} }

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

32 (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

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

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

35 Traversering ved hjælp af en stak (af ikke-færdigbehandlede knuder) Traverseringstypen er bestemt af antallet af gange en knude poppes fra stakken: 1 gang: preorder 2 gange: inorder 3 gange: postorder class StNode { StNode(BinaryNode n) { node = n; } BinaryNode node; int timesPopped; } 1 23

36 Klassen PostOrder public class PostOrder extends TreeIterator { protected Stack s; // Stack of StNode objects public PostOrder(BinaryTree t) { super(t); s = new ArrayStack(); s.push(new StNode(t.root)); } public void first() { s.makeEmpty(); if (t.root != null) s.push(new StNode(t.root)); try { advance(); } catch (NoSuchElementException e) {} } public void advance() {...} }

37 public void advance() { if (s.isEmpty()) { if (current == null) throw new NoSuchElementException(); current = null; return; } for (;;) { StNode cnode = (StNode) s.top(); switch (++cnode.timesPopped) { case 1: if (cnode.node.left != null) s.push(new StNode(cnode.node.left)); continue; case 2: if (cnode.node.right != null) s.push(new StNode(cnode.node.right)); continue; case 3: s.pop(); current = cnode.node; return; } Metoden advance

38 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 NoSuchElementException(); current = null; return; } for (;;) { StNode cnode = (StNode) s.top(); switch (++cnode.timesPopped) { case 1: if (cnode.node.left != null) s.push(new StNode(cnode.node.left)); continue; case 2: s.pop(); current = cnode.node; if (current.right != null) s.push(new StNode(current.right)); return; }

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

40 public void advance() { if (s.isEmpty()) { if (current == null) throw new NoSuchElementExcption(); current = null; return; } current = (BinaryNode) s.topAndPop(); 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.

41 (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.

42 Traversering ved hjælp af korutiner En korutine er en rutine, der midlertidigt kan 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

43 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(); }

44 public class InOrderIterator extends TreeIterator { public InOrderIterator(BinaryTree t) { super(t); } private 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

45 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() { if (current == null) throw new NoSuchElementExcption(); call(this); } public Object retrieve() { if (current == null) throw new NoSuchElementExcption(); return current.element; }

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

47 Designmønstre Designmønster: En model for samspillet imellem objekter, der ind- fanger nyttige strukturer ved løsning af ofte forekommende problemer Eksempler: Container: udgør en beholder for en mængde af objekter. Iterator: giver sekventiel tilgang til objekterne i en container, uden at den 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.

48 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); }

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

50 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); }

51 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

52 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 { public InOrder(Visitor v) { visitor = v; } public void inVisit(Object obj) { visitor.visit(obj); } public boolean isDone() { return visitor.isDone(); } private Visitor visitor; } Visitor for inorder-traversering

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

54 Implementering af ArrayList

55 En kollektion er et objekt, der fungerer som en beholder for andre objekter. Disse kaldes for kollektionens elementer. En mængde (Set) er en uordnet kollektion, som ikke må indeholde dubletter. En liste (List) er en ordnet kollektion, som gerne må indeholde dubletter. Ethvert element har en position. En afbildning (Map) er en uordnet kollektion af nøgle-værdi-par. Nøglerne skal være unikke. Kollektioner

56 Map SortedMap Collection SortedSet SetList Grænseflader for kollektioner java.util.*

57 void add(Object o) void addAll(Collection c) void clear() boolean contains(Object o) boolean containsAll(Collection c) boolean isEmpty() Iterator iterator() void remove(Object o) void removeAll(Collection c) void retainAll(Collection c) int size() interface Collection

58 interface List extends Collection void add(int i, Object o) Object get(int i) int indexOf(Object o) int lastIndexOf(Object o) ListIterator listIterator() ListIterator listIterator(int i) void remove(int i) void set(int i, Object o) List subList(int i, int j) Nye metoder:

59 class AbstractCollection public abstract class AbstractCollection implements Collection { public boolean isEmpty() { return size() == 0; } public void clear() { Iterator itr = iterator(); while (itr.hasNext()) { itr.next(); itr.remove(); } }... } fortsættes

60 public Object[] toArray() { Object[] copy = new Object[size()]; Iterator itr = iterator(); int i = 0; while (itr.hasNext()) copy[i++] = itr.next(); return copy; } fortsættes public boolean contains(Object x) { if (x == null) return false; Iterator itr = iterator(); while (itr.hasNext()) if (x.equals(itr.next())) return true; return false; }

61 public boolean remove(Object x) { if (x == null) return false; Iterator itr = iterator(); while (itr.hasNext()) if (x.equals(itr.next())) { itr.remove(); return true; } return false; } fortsættes

62 public final int hashCode() { int hashVal = 1; Iterator itr = iterator(); while (itr.hasNext()) { Object obj = itr.next(); hashVal = 31 * hashVal + (obj == null ? 0 : obj.hashCode()); } return hashVal; } fortsættes

63 public final boolean equals(Object other) { if (other == this) return true; if (!(other instanceof Collection)) return false; Collection rhs = (Collection) other; if (size() != rhs.size()) return false; Iterator lhsItr = this.iterator(); Iterator rhsItr = rhs.iterator(); while (lhsItr.hasNext()) if (!isEqual(lhsItr.next(), rhsItr.next())) return false; return true; } private boolean isEqual(Object lhs, Object rhs) { if (lhs == null) return rhs == null; return lhs.equals(rhs); }

64 ArrayList En arrayliste ( ArrayList ) er en liste, der benytter et array til at opbevare sine elementer. Collection ListAbstractCollection ArrayList

65 public class ArrayList extends AbstractCollection implements List { public ArrayList() { clear(); } public ArrayList(Collection other) { clear(); Iterator itr = other.iterator(); while (itr.hasNext()) add(itr.next()); } public int size() { return theSize; }... private static final int DEFAULT_CAPACITY = 10; private static final int NOT_FOUND = -1; private Object[] theItems; private int theSize; private int modCount = 0; } fortsættes

66 public void clear() { theSize = 0; theItems = new Object[DEFAULT_CAPACITY]; modCount++; } public Object get(int idx) { if (idx = size()) throw new ArrayIndexOutOfBoundsException( "Index " + idx + "; size " + size()); return theItems[idx]; } public Object set(int idx, Object newVal ) { if (idx = size()) throw new ArrayIndexOutOfBoundsException( "Index " + idx + "; size " + size()); Object old = theItems[idx]; theItems[idx] = newVal; return old; } fortsættes

67 public boolean contains(Object x) { return findPos(x) != NOT_FOUND; } private int findPos(Object x){ for (int i = 0; i < size(); i++) if (x == null) { if (theItems[i] == null) return i; } else if (x.equals(theItems[i])) return i; return NOT_FOUND; } fortsættes

68 public boolean remove(Object x) { int pos = findPos(x); if (pos == NOT_FOUND) return false; remove(pos); return true; } public Object remove(int idx) { Object removedItem = theItems[idx]; for (int i = idx; i < size() - 1; i++) theItems[i] = theItems[i + 1]; theSize--; modCount++; return removedItem; } fortsættes

69 public boolean add(Object x) { if (theItems.length == size()) { Object[] old = theItems; theItems = new Object[theItems.length * 2 + 1]; for (int i = 0; i < size(); i++) theItems[i] = old[i]; } theItems[theSize++] = x; modCount++; return true; } fortsættes

70 public Iterator iterator() { return new ArrayListIterator(0); } public ListIterator listIterator(int idx) { return new ArrayListIterator(idx); } private class ArrayListIterator implements ListIterator { private int current; private int expectedModCount = modCount; private boolean nextCompleted = false; private boolean prevCompleted = false; ArrayListIterator(int pos) { if (pos size()) throw new IndexOutOfBoundsException(); current = pos; }... } fortsættes

71 public boolean hasNext() { if (expectedModCount != modCount) throw new ConcurrentModificationException(); return current < size(); } public boolean hasPrevious() { if (expectedModCount != modCount ) throw new ConcurrentModificationException(); return current > 0; } fortsættes

72 public Object next() { if (!hasNext()) throw new NoSuchElementException(); nextCompleted = true; prevCompleted = false; return theItems[current++]; } public Object previous() { if (!hasPrevious()) throw new NoSuchElementException( ); prevCompleted = true; nextCompleted = false; return theItems[--current]; } fortsættes

73 public void remove() { if (expectedModCount != modCount) throw new ConcurrentModificationException( ); if (nextCompleted) ArrayList.this.remove(--current); else if (prevCompleted) ArrayList.this.remove(current); else throw new IllegalStateException(); prevCompleted = nextCompleted = false; expectedModCount++; }

74 Læs kapitel 19 Afsnit 19.6 kan læses kursorisk Løs følgende opgaver Opgave 34: 15.9 (1 point) Opgave 35: 16.1 (2 point) Opgave 36: 16.5 (2 point, ikke-obligatorisk) Opgave 37: 17.3 (2 point) Opgave 38: (2 point, ikke-obligatorisk) Opgave 39: 18.3 (1 point) Opgave 40: 18.9 (2 point, ikke-obligatorisk) Afleveringsfrist: tirsdag den 4. december Ugeseddel november november