De presentatie wordt gedownload. Even geduld aub

De presentatie wordt gedownload. Even geduld aub

1 Hoofdstuk 20: GEGEVENSSTRUCTUREN. 2 H 20. GEGEVENSSTRUCTUREN 1. INLEIDING Reeds gezien : gegevensstructuren met een vaste lengte - Eéndimensionele arrays.

Verwante presentaties


Presentatie over: "1 Hoofdstuk 20: GEGEVENSSTRUCTUREN. 2 H 20. GEGEVENSSTRUCTUREN 1. INLEIDING Reeds gezien : gegevensstructuren met een vaste lengte - Eéndimensionele arrays."— Transcript van de presentatie:

1 1 Hoofdstuk 20: GEGEVENSSTRUCTUREN

2 2 H 20. GEGEVENSSTRUCTUREN 1. INLEIDING Reeds gezien : gegevensstructuren met een vaste lengte - Eéndimensionele arrays - Meerdimensionele arrays

3 3 H 20. GEGEVENSSTRUCTUREN 1. INLEIDING H 20: Dynamische gegevensstructuren – Variabele lengte: lengte kan kleiner en groter worden tijdens runtime. – Enkele dynamische gegevensstructuren: Gelinkte lijsten Stacks Queues Binaire bomen

4 4 2. ZELF-REFERENTIE KLASSE Zelf-referentie klasse –Bevat een instantie-variabele dat refereert naar een object van dezelfde klasse. Bv: class Node { // Node = knoop private int data; private Node nextNode; public Node (int data) {…} // constructor public void setData (int data) {…} public int getData() {…} public void setNext (Node next) {…} public Node getNext() {…} }

5 5 2. ZELF-REFERENTIE KLASSE private Node nextNode; De instantie-variabele nextNode wordt een "link" genoemd. –nextNode verbindt ("links") een Node object met een ander Node object.

6 6 2. ZELF-REFERENTIE KLASSE Programma’s kunnen "zelf-referentie objecten" verbinden. Zo kan er een gegevensstructuur gecreëerd worden zoals lijsten, queues, stacks en bomen. Bv: 1510

7 7 3. DYNAMISCHE GEHEUGENTOEWIJZING Dynamische geheugentoewijzing –Als we objecten aan de dynamische gegevensstructuur toevoegen, verzoeken we het systeem om meer geheugen. –Als we een object niet meer nodig hebben, geven we de ruimte aan het systeem terug: JAVA heeft een automatische garbage collection.

8 8 3. DYNAMISCHE GEHEUGENTOEWIJZING Declaratie en creatie van nodeToAdd Node nodeToAdd = new Node ( 10 ); - De expressie " new Node (10) " kent geheugen toe om het Node object te bewaren en geeft een referentie van het object terug. Deze referentie wordt toegekend aan nodeToAdd. - Indien geheugen tekort dan geeft deze expressie OutOfMemoryError terug.

9 9 4. GELINKTE LIJSTEN Gelinkte lijst –is een lineaire (sequentiële) collectie van zelf- referentie objecten (= nodes = knopen). –Knopen kunnen toegevoegd en verwijderd worden aan het begin, midden of eind van de lijst. –Elke knoop bevat een referentie naar de volgende, alleen de laatste knoop heeft niks om naar te verwijzen  de laatste knoop bevat null.

10 10 4. ENKEL GELINKTE LIJST firstNode... HD Q lastNode –Een object bevat de referentie van de eerste knoop van de gelinkte lijst (firstNode). Het object kan ook de referentie van de laatste knoop bevatten (lastNode).

11 11 4. DUBBEL GELINKTE LIJST firstNode... H Q lastNode Bv: class Node { private Node previousNode; private int data; private Node nextNode; D

12 12 4. VOORBEELD VAN EEN ENKEL GELINKTE LIJST Voorbeeld: Drie domeinklassen: ListNode, List en EmptyListException Applicatie: ListTest ListNode is een zelf-referentie klasse. De objecten van deze klasse zijn de knopen van de gelinkte lijst. List zal verwerkingen met de gelinkte lijst uitvoeren: toevoegen en verwijderen van knopen. EmptyListException werpt een exception indien er een poging wordt gedaan om een knoop uit een lege lijst te verwijderen.

13 13 4. KLASSE ListNode class ListNode { private Object data; private ListNode nextNode; // constructors ListNode( Object object ) { this( object, null ); } ListNode( Object object, ListNode node ) { data = object; nextNode = node; } // accessors en mutators Object getData() { return data; } void setData(Object data) { this.data = data;} ListNode getNext() { return nextNode; } void setNext(ListNode node) { nextNode = node; } } // einde klasse ListNode De zelf-referentie klasse ListNode bevat "data" en de link "nextNode". "data" is een referentie naar een object van de klasse Object, dus kan "data" refereren naar gelijk welk object.

14 14 4. KLASSE List Klasse List:  Attributen: firstNode, lastNode, name  Constructors In de constructors wordt er een naam aan de gelinkte lijst toegekend.  Methodes : isEmpty : controleren indien de lijst al dan niet leeg is; print : de inhoud van de gelinkte lijst wordt teruggegeven als string; insertAtFront : knoop vooraan in de lijst toevoegen; insertAtBack : knoop achteraan in de lijst toevoegen; removeFromFront : knoop vooraan in de lijst verwijderen; removeFromBack : knoop achteraan in de lijst verwijderen.

15 15 4. KLASSE List : instantie-variabelen en constructors public class List { private ListNode firstNode; private ListNode lastNode; private String name; // constructors public List() { this( "list" ); } public List( String listName ) { name = listName; } "firstNode" referereert naar de eerste knoop en "lastNode" refereert naar de laatste knoop van de gelinkte lijst. “name" zal de naam van de gelinkte lijst bijhouden. De attributen "firstNode" en "lastNode" worden automatisch op null gezet.

16 16 4. KLASSE List : accessors en mutators protected ListNode getFirstNode() { return firstNode; } protected ListNode getLastNode() { return lastNode; } public String getName() { return name; } protected void setFirstNode(ListNode node) { firstNode = node; } protected void setLastNode(ListNode node) { lastNode = node; } public void setName(String name) { this.name = name; }

17 17 4. KLASSE List: methode isEmpty // controleert indien de gelinkte lijst al dan niet leeg is public synchronized boolean isEmpty() { return firstNode == null; // return true indien de lijst // leeg is } De methode isEmpty is een "predicate method". Deze methode test een conditie van een object zonder dat object te wijzigen. synchronized om zeker te zijn dat de toestand niet wijzigt tijdens de uitvoering van deze methode.

18 18 // de inhoud van de knopen weergeven public synchronized String print(){ if ( isEmpty() ) return "Empty " + name ; StringBuffer buffer = new StringBuffer(); ListNode current = firstNode; // zolang niet einde lijst wordt de inhoud van de // huidige knoop (= current) weergegeven. Vervolgens wordt // de huidige knoop gelijkgesteld aan de volgende knoop while ( current != null ) { buffer.append( current.getData().toString() + " " ); current = current.getNext(); } return buffer.toString(); } // einde methode print 4. KLASSE List: methode print

19 19 4. KLASSE List : methode insertAtFront // voegt een knoop toe aan het begin van de gelinkte lijst public synchronized void insertAtFront( Object insertItem ) { if ( isEmpty() ) firstNode = lastNode = new ListNode( insertItem ); else firstNode = new ListNode( insertItem, firstNode ); } Indien de gelinkte lijst leeg is dan zal firstNode en lastNode naar de nieuwe knoop wijzen. Indien de lijst niet leeg is dan zal firstNode naar de nieuwe eerste knoop wijzen.

20 20 4. KLASSE List : methode insertAtFront Schematische voorstelling van insertAtFront: Indien de gelinkte lijst leeg is dan zal firstNode en lastNode naar de nieuwe knoop wijzen. firstNode new Listnode firstNode new Listnode (a) (b) lastNode

21 21 4. KLASSE List : methode insertAtFront Schematische voorstelling van insertAtFront Indien de gelinkte lijst niet leeg is dan zal firstNode naar de nieuwe knoop wijzen. firstNode new Listnode firstNode new Listnode (a) (b) lastNode

22 22 4. KLASSE List : methode insertAtBack // voegt een knoop toe aan het einde van de lijst public synchronized void insertAtBack( Object insertItem ) { if ( isEmpty() ) firstNode = lastNode = new ListNode( insertItem ); else // lastNode's nextNode zal naar de nieuwe node wijzen { lastNode.setNext(new ListNode( insertItem )); lastNode = lastNode.getNext();} } Indien de gelinkte lijst leeg is dan zal firstNode en lastNode naar de nieuwe knoop wijzen. Indien de lijst niet leeg is dan zal lastNode's nextNode naar de nieuwe knoop wijzen. M.a.w. de knoop die op de laatste plaats stond wijst nu naar de nieuwe knoop. Vervolgens wijst lastNode naar de nieuwe knoop.

23 23 4. KLASSE List : methode insertAtBack Schematische voorstelling van insertAtBack: Indien de gelinkte lijst leeg is dan zal firstNode en lastNode naar de nieuwe knoop wijzen. firstNode 2 2 new Listnode firstNode new Listnode (a) (b) lastNode

24 24 4. KLASSE List : methode insertAtBack Schematische voorstelling van insertAtBack: Indien de lijst niet leeg is dan zal lastNode's nextNode naar de nieuwe knoop wijzen. Vervolgens zal lastNode naar de nieuwe knoop wijzen. firstNode 12 new Listnode (a) (b) firstNodenew Listnode lastNode

25 25 4. KLASSE List : methode removeFromFront // verwijdert de eerste knoop van de gelinkte lijst public synchronized Object removeFromFront() throws EmptyListException { if ( isEmpty() ) // exception wordt gegooid indien de // gelinkte lijst leeg is throw new EmptyListException( name ); Object removedItem = firstNode.getData(); // de data van de // eerste knoop in de lijst wordt toegekend aan removedItem // firstNode wordt gewijzigd. lastNode wordt gewijzigd // indien de lijst maar één knoop bevat. if ( firstNode == lastNode ) firstNode = lastNode = null; else firstNode = firstNode.getNext(); return removedItem; // de data van de verwijderde knoop // wordt teruggegeven. } // einde methode removeFromFront

26 26 4. KLASSE List : methode removeFromFront Schematische voorstelling van removeFromFront : Indien de gelinkte lijst één knoop bevat dan zal na deze methode firstNode en lastNode aan null worden toegekend. firstNode 5 removeItem (b)(b) ab) lastNode 5

27 27 4. KLASSE List : methode removeFromFront Schematische voorstelling van removeFromFront : Indien de lijst meer dan één knoop bevat dan zal firstNode naar de tweede knoop wijzen. firstNode 12 (a) (b) lastNode firstNode removeItem

28 28 4. KLASSE List : methode removeFromBack // verwijdert de laatste knoop van de gelinkte lijst public synchronized Object removeFromBack() throws EmptyListException { if ( isEmpty() ) // exception wordt gegooid indien de // gelinkte lijst leeg is throw new EmptyListException( name ); Object removedItem = lastNode.getData(); // de data van de // laatste knoop in de lijst wordt toegekend aan removedItem // lastNode wordt gewijzigd. firstNode wordt gewijzigd // indien de lijst maar één knoop bevat. if ( firstNode == lastNode ) firstNode = lastNode = null; else

29 29 4. KLASSE List : methode removeFromBack // de lijst bevat meer dan één knoop : { // de nieuwe laatste knoop zoeken (m.a.w. de voorlaatste // knoop zoeken ListNode current = firstNode; // de gelinkte lijst doorlopen totdat de current.nextnode // (= de volgende knoop in de lijst) gelijk is aan lastnode while (current.getNext() != lastNode ) current = current.getNext(); lastNode = current; // current is de nieuwe laatste knoop current.setNext(null); // vermits current de nieuwe // laatste knoop is, is er geen volgende knoop meer } return removedItem; // de data van de verwijderde knoop // wordt teruggegeven. } // einde methode removeFromBack

30 30 4. KLASSE List : methode removeFromBack Schematische voorstelling van removeFromBack : Indien de gelinkte lijst één knoop bevat dan zal na deze methode firstNode en lastNode aan null worden toegekend. firstNode 7 removeItem (b)(b) ab) lastNode 7

31 31 4. KLASSE List : methode removeFromBack Schematische voorstelling van removeFromBack : Indien de lijst meer dan één knoop bevat dan zal lastNode naar de nieuwe laatste knoop wijzen. 12 (a) (b) lastNode lastNode firstNode removeItem firstNodecurrent

32 32 4. KLASSE List : synchronized Als we de klasse binnen één thread gebruiken, gaat alles goed, maar wat gebeurt er wanneer meerdere threads de methoden op precies (of bijna) dezelfde tijd kunnen benaderen? Stel bvb. dat één thread een knoop verwijdert en dat tegerlijkertijd een ander de inhoud opvraagt. Moet de geretourneerde inhoud, de verwijderde knoop, al dan niet bevatten? Eigenlijk worden de gegevens onbetrouwbaar. Door het sleutelwoord synchronized te gebruiken, weten we zeker dat slechts één thread tegerlijkertijd een methode benadert. Elke andere thread moet wachten totat het object weer vrij is.

33 33 4. KLASSE EmptyListException public class EmptyListException extends RuntimeException { // constructors public EmptyListException() { this( "List" ); // roept de constructor met één // parameter, van deze klasse, op } public EmptyListException( String name ) { super( name + " is empty" ); // roept de // constructor van zijn superklasse op } } // einde klasse EmptyListException Exception wordt gegooid indien het programma een knoop uit een lege lijst wenst te verwijderen.

34 34 public class ListTest { public static void main( String args[] ) { List list = new List(); // de lege gelinkte lijst "list" is // gecreëerd. // objects creëren om nadien in de gelinkte lijst te zetten Boolean bool = Boolean.TRUE; Character character = new Character( '$' ); Integer integer = new Integer( ); String string = "hello"; // knopen in de lijst toevoegen en vervolgens de inhoud weergeven list.insertAtFront( bool ); System.out.println( list.print()); list.insertAtFront( character ); System.out.println( list.print()); list.insertAtBack( integer ); System.out.println( list.print()); list.insertAtBack( string ); System.out.println( list.print()); The list is: true The list is: $ true The list is: $ true The list is: $ true hello 4. KLASSE ListTest

35 35 4. KLASSE ListTest // knopen verwijderen uit de gelinkte lijst try { Object removedObject = list.removeFromFront(); System.out.println( removedObject.toString() + " removed" ); System.out.println( list.print()); removedObject = list.removeFromFront();... removedObject = list.removeFromBack();... } // einde try blok // catch exception indien een poging werd uitgevoerd om een // knoop uit een lege lijst te verwijderen catch ( EmptyListException emptyListException ) { emptyListException.printStackTrace(); } } // einde methode main } // einde klasse ListTest

36 36 4. KLASSE ListTest Uitvoer van : list.print(); Object removedObject = list.removeFromFront();... removedObject = list.removeFromFront();... removedObject = list.removeFromBack();... The list is: $ true hello $ removed The list is: true hello true removed The list is: hello hello removed The list is: removed Empty list

37 37 OEFENING Schrijf een dubbel gelinkte lijst Klasse DoubleListNode : zie slide 11 Klasse DoubleList : insertAtFront, insertAtBack en printInverse (herschrijf de klasse List)

38 38 5. STACKS: VOORBEELD 1 Voorbeeld 1: –We zullen een stack implementeren door gebruik te maken van de klasse List De klasse StackInheritance zal erven van List.

39 39 5. KLASSE StackInheritance public class StackInheritance extends List { // constructor public StackInheritance() { super( "stack" ); } // voegt een object aan de stack toe public synchronized void push( Object object ) { insertAtFront( object ); } // verwijdert een object van de stack public synchronized Object pop() throws EmptyListException { return removeFromFront();} } // einde klasse StackInheritance De klasse StackInheritance erft van List, omdat een stack een beperkte versie is van een gelinkte lijst. De methoden isEmpty en print kunnen gestuurd worden naar een object van StackInheritance, omdat deze erft van List

40 40 5. KLASSE StackInheritanceTest public class StackInheritanceTest {... StackInheritance stack = new StackInheritance(); Boolean bool = Boolean.TRUE; Character character = new Character( '$' ); stack.push( bool ); stack.push( character );... while ( true ) { removedObject = stack.pop();... }... (1) (2) (3) (4) (5) ($ popped) (true popped) $ zie volgende slide true true true

41 41 5. KLASSE StackInheritanceTest com.deitel.jhtp5.ch20.EmptyListException: stack is empty at com.deitel.jhtp5.ch20.List.removeFromFront(List.java:82) at com.deitel.jhtp5.ch20.StackInheritance.pop( StackInheritance.java:22) at StackInheritanceTest.main(StackInheritanceTest.java:33)

42 42 5. STACKS: VOORBEELD 2 Andere manier om een stack te implementeren: De klasse StackComposition zal een referentie naar een List bevatten. Deze manier van implementatie heet "composition". Voordeel t.o.v. voorbeeld 1 (overerving): Deze stack bevat enkel de vier nodige methodes (push, pop, isEmpty en print). De methodes van List (removeFromBack, insertAtBack, …) zijn nu geen methodes van de stack. Terwijl dit bij overerving wel het geval was.

43 43 5. KLASSE StackComposition public class StackComposition { private List stackList; public StackComposition() { stackList = new List( "stack" ); } public synchronized void push( Object object ) { stackList.insertAtFront( object ); } public synchronized Object pop() throws EmptyListException { return stackList.removeFromFront(); } public synchronized boolean isEmpty() { return stackList.isEmpty(); } public synchronized String print() { return stackList.print(); } } // einde klasse StackComposition

44 44 6. QUEUES Queue (= wachtrij) –is ook een beperkte versie van een gelinkte lijst. –Men kan zich een queue voorstellen als een rij bij een loket, waarbij de voorste in de rij als eerste geholpen wordt en nieuwkomers achter aansluiten. De persoon die het eerst in de rij staat, wordt het eerst bediend  queue is een FIFO gegevensstructuur: first-in, first-out.

45 45 6. QUEUES –Het element van de queue dat vooraan staat in de queue, dat dus als eerste zal worden verwijderd, heet de kop van de queue. –Het element dat achteraan staat, dat dus als laatste aan de queue is toegevoegd, heet de staart van de queue –We spreken hier niet van push en pop maar van enqueue en dequeue.  enqueue : element toevoegen aan de queue  dequeue : element verwijderen uit de queue

46 46 6. QUEUE: VOORBEELD Voorbeeld: –We zullen een queue implementeren door gebruik te maken van de klasse List De klasse Queue zal een referentie naar een List bevatten ("composition").

47 47 6. KLASSE QUEUE public class Queue { private List queueList; public Queue() { queueList = new List( "queue" ); } // element toevoegen aan de queue public synchronized void enqueue( Object object ) { queueList.insertAtBack( object ); } // element verwijderen uit de queue public synchronized Object dequeue() throws EmptyListException { return queueList.removeFromFront(); } public synchronized boolean isEmpty() { return queueList.isEmpty(); } public synchronized String print() {return queueList.print();} } // einde klasse Queue

48 48 6. KLASSE QueueTest public class QueueTest {... Queue queue = new Queue(); Boolean bool = Boolean.TRUE; Character character = new Character( '$' ); queue.enqueue( bool ); queue.enqueue( character );... while ( true ) {removedObject = queue.dequeue();... }... (1) (2) (3) (4) (5) (true dequeued) ($ dequeued) true true $ $ zie volgende slide kop staart kop staart kop staart

49 49 6. KLASSE QueueTest com.deitel.jhtp5.ch20.EmptyListException: queue is empty at com.deitel.jhtp5.ch20.List.removeFromFront(List.java:88) at com.deitel.jhtp5.ch20.Queue.dequeue(Queue.java:23) at QueueTest.main(QueueTest.java:33)

50 50 OEFENING Gegeven : De queue bestaat uit een array van 5 elementen. De array houdt gehele getallen bij. Gevraagd: Schrijf de klasse Queue : constructor en de methodes enqueue en dequeue.

51 51 7. BINAIRE BOOM - Binaire boom is óf leeg óf zij bestaat uit de wortel, en twee binaire bomen, de linker subboom en de rechter subboom. M.a.w. de knopen bevatten twee " links ". -Het linkerkind is de eerste knoop in de linker subboom. -Het rechterkind is de eerste knoop in de rechter subboom.

52 52 7. BINAIRE BOOM Voorbeeld van een binaire boom - Een programma bevat de referentie van de wortel van de binaire boom (root). B AD C root

53 53 7. BINAIRE ZOEKBOOM -binaire zoekboom is een binaire boom die óf leeg is óf waarin elke knoop een sleutel bevat die voldoet aan de volgende voorwaarden: –De sleutel van het linkerkind (als deze bestaat) van een knoop is kleiner dan de sleutel van de ouders. –De sleutel van het rechterkind (als deze bestaat) van een knoop is groter dan de sleutel van de ouders.

54 54 7. BINAIRE ZOEKBOOM Voorbeeld van een binaire zoekboom

55 55 7. BINAIRE ZOEKBOOM -Hoe een binaire zoekboom eruit ziet hangt af van de volgorde van de ingegeven sleutels. -Bv. (1) Voeg 22 toe (3) Voeg 35 toe (2) Voeg 10 toe (4) Voeg 15 toe

56 56 7. BINAIRE ZOEKBOOM Voordeel van een binaire zoekboom t.o.v. gesorteerde gelinkte lijst –Indien we een sleutel moeten opzoeken in een enkel gelinkte lijst dan kunnen we niets anders dan knoop voor knoop door de lijst te bewegen (sequentieel zoeken). Maar sequentieel zoeken is vergeleken bij binair zoeken erg langzaam. –Indien we met de elementen van een gesorteerde lijst een binaire zoekboom construeren, zullen we zien dat we een sleutel kunnen opzoeken in O(log n) stappen, net zoals bij binair zoeken. Bovendien kunnen elementen in de tijd O(log n) toegevoegd of verwijderd worden.

57 57 7. DOORLOPEN VAN DE BINAIRE BOOM –Eén van de belangrijkste operaties bij binaire bomen is het doorlopen van de boom, waarbij elke knoop bezocht wordt. Het doorlopen van een gelinkte lijst gaat in de natuurlijke volgorde van de eerste tot de laatste knoop. Een boom kunnen we echter in vele verschillende volgorden doorlopen.

58 58 7. DOORLOPEN VAN DE BINAIRE BOOM In een gegeven knoop zijn er drie taken die we in een of andere volgorde willen uitvoeren: het bezoeken van de knoop zelf, het doorlopen van zijn linker subboom en het doorlopen van zijn rechter subboom. Gewoonlijk beperkt men zich tot de gevallen waarin de linker subboom voor de rechter wordt doorlopen. M.a.w. men beperkt zich tot drie gevallen. Deze hebben speciale namen: preorder, inorder en postorder.

59 59 7. DOORLOPEN VAN DE BINAIRE BOOM doorlopen in preorder : de knoop wordt eerst bezocht. Als tweede de linker subboom en al laatste de rechter subboom. Bv. 20, 8, 33, 27,

60 60 7. DOORLOPEN VAN DE BINAIRE BOOM doorlopen in inorder : de linker subboom wordt eerst bezocht. Als tweede de knoop en al laatste de rechter subboom. Bv. 8, 20, 27, 33,

61 61 7. DOORLOPEN VAN DE BINAIRE BOOM doorlopen in postorder : de linker subboom wordt eerst bezocht. Als tweede de rechter subboom en al laatste de knoop. Bv. 8, 27, 41, 33,

62 62 7. OEFENING Bepaal de uitvoer indien de boom wordt doorlopen in: (1) preorder (2) inorder (3) postoder

63 63 7. VOORBEELD VAN EEN BINAIRE BOOM Voorbeeld: Twee domeinklassen: TreeNode en Tree Applicatie: TreeTest TreeNode: De objecten van deze klasse zijn de knopen van de binaire zoekboom. Bevat de methode insert: een knoop wordt toegevoegd aan de boom. Tree bevat de instantie-variable " root ". Deze zal refereren naar de wortel van de binaire zoekboom. Bevat methodes om de boom te doorlopen en om knopen toe te voegen.

64 64 7. KLASSE TreeNode class TreeNode { private TreeNode leftNode; private int data; private TreeNode rightNode; // constructor public TreeNode( int nodeData ) { data = nodeData; leftNode = rightNode = null;// de knoop heeft geen kinderen } leftNode is het linkerkind en rightNode is het rechterkind. In de constructor wordt er een blad ( " leaf node " ) gecreëerd. De ingegeven data wordt in het blad geplaatst.

65 65 7. KLASSE TreeNode : accessors public void setLeftNode(TreeNode leftNode) { this.leftNode = leftNode; } public void setRightNode(TreeNode rightNode) { this.rightNode = rightNode; } public void setData(int data) { this.data = data; } public TreeNode getLeftNode() { return leftNode; } public TreeNode getRightNode() { return rightNode; } public int getData() { return data; } In het boek zijn de instantie-variabelen als package- toegankelijk gedeclareerd.

66 66 7. KLASSE TreeNode : methode insert // locate insertion point and insert new node; ignore duplicate values public synchronized void insert( int insertValue ) { // insert in left subtree if ( insertValue < data ) { // insert new TreeNode if ( leftNode == null ) leftNode = new TreeNode( insertValue ); else // continue traversing left subtree leftNode.insert( insertValue ); } // insert in right subtree else if ( insertValue > data ) { // insert new TreeNode if ( rightNode == null ) rightNode = new TreeNode( insertValue ); else // continue traversing right subtree rightNode.insert( insertValue ); } } // end method insert } // end class TreeNode

67 67 7. KLASSE TreeNode : methode insert Een knoop kan enkel toegevoegd worden in de binaire boom als een blad ( " leaf node " ). De methode insert is recursief. De toe te voegen waarde "insertValue" wordt vergeleken met de waarde, die in de wortel staat "data". Indien de toe te voegen waarde kleiner is "if (insertValue

68 68 7. KLASSE Tree public class Tree { private TreeNode root; // constructor: de binaire boom is leeg public Tree() { root = null; } public void setRoot(TreeNode root) { this.root = root; } public TreeNode getRoot() { return root; }

69 69 7. KLASSE Tree // een knoop toevoegen in de binaire zoekboom public synchronized void insertNode( int insertValue ) { if ( root == null ) root = new TreeNode( insertValue ); // de wortel // ("root node") wordt gecreëerd else root.insert( insertValue ); // methode insert oproepen } Indien de boom leeg is dan is de instantie-variable " root " gelijk aan null, anders refereert " root " naar de wortel.

70 70 7. KLASSE Tree : inorder // doorlopen van de boom volgens inorder public synchronized void inorderTraversal() { inorderHelper( root ); } // recursieve methode om de boom te doolopen volgens inorder private void inorderHelper( TreeNode node ) { if ( node == null ) return; inorderHelper( node.getLeftNode()); // doorloop linker subboom System.out.print( node.getData()+ " " ); // inhoud van de // knoop weergeven inorderHelper( node.getRightNode());//doorloop rechter subboom } Indien de programmeur de boom wenst te doorlopen kan hij een methode oproepen, zonder dat hij de "root" dient door te geven (bv. methode inorderTraversal).

71 71 Voorbeeld: root  27 inorderHelper( node.getLeftNode() ); 1 System.out.print( node.getData()+" "); inorderHelper( node.getRightNode() ); root  13 inorderHelper( node.getLeftNode() ); 2System.out.print( node.getData()+" "); 8 inorderHelper( node.getRightNode()); root  6 root  null inorderHelper( node.getLeftNode() ); return; System.out.print( node.getData() + " " ); 5 inorderHelper( node.getRightNode()); 3 6 root  17 4 root  null inorderHelper( node.getLeftNode() ); return; System.out.print( node.getData()+" " ); 7 inorderHelper( node.getRightNode());

72 72 7. KLASSE Tree : preorder // doorlopen van de boom volgens preorder public synchronized void preorderTraversal() { preorderHelper( root ); } // recursieve methode om de boom te doolopen volgens preorder private void preorderHelper( TreeNode node ) { if ( node == null ) return; System.out.print( node.getData()+ " " ); // inhoud van de // knoop weergeven preorderHelper( node.getLeftNode()); //doorloop linker subboom preorderHelper(node.getRightNode());//doorloop rechter subboom } Preorder– data weergeven, vervolgens doorloop linker subboom en als laatste doorloop rechter subboom

73 73 7. KLASSE Tree : postorder // begin postorder traversal public synchronized void postorderTraversal() { postorderHelper( root ); } // recursive method to perform postorder traversal private void postorderHelper( TreeNode node ) { if ( node == null ) return; postorderHelper( node.getLeftNode()); //doorloop linker subboom postorderHelper(node.getRightNode());//doorloop rechter subboom System.out.print( node.getData() + " " ); // inhoud van de // knoop weergeven } } // einde klasse Tree Postorder – doorloop linker subboom, vervolgens doorloop rechter subboom en als laatste de data weergeven

74 74 7. KLASSE TreeTest... public static void main( String args[] ) { Tree tree = new Tree(); int value; // voeg 10 random getallen van 0-99 in de binare zoekboom for ( int i = 1; i <= 10; i++ ) { value = ( int ) ( Math.random() * 100 ); System.out.print( value + " " ); tree.insertNode( value ); } tree.preorderTraversal(); // doorlopen volgens preorder tree.inorderTraversal(); // doorlopen volgens inorder tree.postorderTraversal(); // doorlopen volgens postorder...

75 75 7. KLASSE TreeTest uitvoer Inserting the following values: Preorder traversal Inorder traversal Postorder traversal


Download ppt "1 Hoofdstuk 20: GEGEVENSSTRUCTUREN. 2 H 20. GEGEVENSSTRUCTUREN 1. INLEIDING Reeds gezien : gegevensstructuren met een vaste lengte - Eéndimensionele arrays."

Verwante presentaties


Ads door Google