diff --git a/Chapter 15 Activities/SentenceReverser/src/SentenceReverser.java b/Chapter 15 Activities/SentenceReverser/src/SentenceReverser.java index 753ae08..7578631 100644 --- a/Chapter 15 Activities/SentenceReverser/src/SentenceReverser.java +++ b/Chapter 15 Activities/SentenceReverser/src/SentenceReverser.java @@ -2,25 +2,53 @@ import java.util.Stack; /** - * Class for reversing the order of a sentence. + Class for reversing the order of a sentence. */ public class SentenceReverser { /** - * Reverses the given sentence. - * - * @param sentence Sentence to be reversed. - * @return reversed sentence. + Reverses the given sentence. + @param sentence Sentence to be reversed. + @return reversed sentence. */ public static String reverse(String sentence) { - // Complete this method. Use a Stack. - ... - - - - - - + String reversed = ""; + Scanner scanner = new Scanner(sentence); + Stack stack = new Stack<>(); + while (scanner.hasNext()) + { + String pushWord = scanner.next(); + stack.push(pushWord); + if (pushWord.contains(".")) + { + boolean firstWord = true; + while (stack.size() > 0) + { + String popWord = stack.pop(); + if (firstWord) + { + String firstLetter = popWord.substring(0, 1); + popWord = firstLetter.toUpperCase() + popWord.substring(1); + firstWord = false; + } + else + { + popWord = popWord.toLowerCase(); + } + popWord = popWord.replace(".", ""); + reversed += popWord; + if (stack.size() <= 0) + { + reversed += "."; + } + if (scanner.hasNext() || (stack.size() > 0)) + { + reversed += " "; + } + } + } + } + return reversed; } } diff --git a/Chapter 15 Class Notes/src/ListDemo.java b/Chapter 15 Class Notes/src/ListDemo.java index 05852f5..3d761f3 100644 --- a/Chapter 15 Class Notes/src/ListDemo.java +++ b/Chapter 15 Class Notes/src/ListDemo.java @@ -9,5 +9,118 @@ public class ListDemo { public static void main(String[] args) { + /* + The addLast method can be used to populate a list. + */ + LinkedList staff = new LinkedList<>(); + staff.addLast("Diana"); + staff.addLast("Harry"); + staff.addLast("Romeo"); + staff.addLast("Tom"); + + // The list is currently: DHRT + + /* + The listIterator method creates a new list iterator that is + positioned at the front of the list. + The "|" in the comment indicates the iterator position. + */ + ListIterator iterator = staff.listIterator(); // |DHRT + + /* + The next method advances the iterator over the next element + in the list. + */ + iterator.next(); // D|HRT + + /* + The next method also returns the element that the iterator + is passing. + */ + String name = iterator.next(); // DH|RT + System.out.println(name); + System.out.println("Expected: Harry"); + + /* + The add method inserts an element at the iterator position. + The iterator is then positioned after the element that was added. + */ + iterator.add("Juliet"); // DHJ|RT + iterator.add("Nina"); // DHJN|RT + + /* + The remove method removes the element returned by the last + call to next or previous. + The remove method can only be called once after calling next + or previous. + The remove method cannot be called after calling add. + */ + iterator.next(); // DHJNR|T + iterator.remove(); // DHJN|T + + System.out.println(staff); + System.out.println("Expected: [Diana, Harry, Juliet, Nina, Tom]"); + + /* + The set method updates the element returned by the last call + to next or previous. + */ + iterator.previous(); // DHJ|NT + iterator.set("Albert"); // DHJ|AT + + /* + The hasNext method is often used in the context of a while loop. + */ + iterator = staff.listIterator(); // |DHJAT + while(iterator.hasNext()) + { + String n = iterator.next(); + if(n.equals("Juliet")) + { + // DHJ|AT + iterator.remove(); // DH|AT + } + } + // DHAT| + + /* + Enhanced for loops work with linked lists! + */ + for(String n : staff) + { + System.out.print(n + " "); + } + System.out.println(); + System.out.println("Expected: Diana, Harry, Albert, Tom"); + + /* + ConcurrentModificationException + + Cannot modify a linked list while also using an iterator + unless you use that iterator to so. + */ + iterator = staff.listIterator(); + while(iterator.hasNext()) + { + String n = iterator.next(); + if(n.equals("Harry")) + { + //staff.remove("Diana"); + } + } + + /* + ConcurrentModificationException + + The enhanced for loop automatically creates an iterator! + That's how it works! + */ + for(String n : staff) + { + if(n.equals("Harry")) + { + staff.add("Charlie"); + } + } } } diff --git a/Chapter 15 Class Notes/src/MapDemo.java b/Chapter 15 Class Notes/src/MapDemo.java index 835c1ba..413e968 100644 --- a/Chapter 15 Class Notes/src/MapDemo.java +++ b/Chapter 15 Class Notes/src/MapDemo.java @@ -11,5 +11,36 @@ public class MapDemo { public static void main(String[] args) { + /* + The Map interface is a generic. The first type is the type + of the key; the second, the type of the value. + */ + Map favoriteColors = new HashMap<>(); + + favoriteColors.put("Brian", Color.RED); + favoriteColors.put("Minghan", Color.ORANGE); + favoriteColors.put("Dylan", Color.BLUE); + favoriteColors.put("Daniel", Color.MAGENTA); + favoriteColors.put("Robert", Color.CYAN); + + // two different keys can have the same value + favoriteColors.put("Schmit", Color.MAGENTA); + + // but the same key cannot have two different values + // this changes the value for the key "Daniel" + favoriteColors.put("Daniel", Color.RED); + + // create a set of the keys in the map + Set keySet = favoriteColors.keySet(); + + for(String key : keySet) + { + System.out.println(key + " (" + key.hashCode() + "): " + + favoriteColors.get(key)); + } + + + + } } diff --git a/Chapter 15 Class Notes/src/PriorityQueueDemo.java b/Chapter 15 Class Notes/src/PriorityQueueDemo.java index e27bc2c..23e7db5 100644 --- a/Chapter 15 Class Notes/src/PriorityQueueDemo.java +++ b/Chapter 15 Class Notes/src/PriorityQueueDemo.java @@ -10,5 +10,19 @@ public class PriorityQueueDemo { public static void main(String[] args) { + // create a priority queue of to-do items + Queue q = new PriorityQueue<>(); + + q.add(new WorkOrder(3, "vacuum carpets")); + q.add(new WorkOrder(2, "water plants")); + q.add(new WorkOrder(2, "make dinner")); + q.add(new WorkOrder(2, "walk dog")); + q.add(new WorkOrder(10, "play video games")); + q.add(new WorkOrder(1, "take Chapter 15 practice quiz")); + + while(q.size() > 0) + { + System.out.println(q.remove()); + } } } diff --git a/Chapter 15 Class Notes/src/QueueDemo.java b/Chapter 15 Class Notes/src/QueueDemo.java index 1da9ca9..980bc7b 100644 --- a/Chapter 15 Class Notes/src/QueueDemo.java +++ b/Chapter 15 Class Notes/src/QueueDemo.java @@ -9,5 +9,27 @@ public class QueueDemo { public static void main(String[] args) { + // create a print queue of strings (using a linked list) + Queue jobs = new LinkedList<>(); + + // add several print jobs + jobs.add("Joe: Expense Report #1"); + jobs.add("Cathy: Meeting Memo"); + + System.out.println("Printing: " + jobs.remove()); + + jobs.add("Cathy: Purchase Order #1"); + jobs.add("Joe: Expense Report #2"); + jobs.add("Joe: Weekly Report"); + + System.out.println("Printing: " + jobs.remove()); + + jobs.add("Cathy: Purchase Order #2"); + + // print the rest of the jobs in the queue + while(jobs.size() > 0) + { + System.out.println("Printing: " + jobs.remove()); + } } } diff --git a/Chapter 15 Class Notes/src/StackDemo.java b/Chapter 15 Class Notes/src/StackDemo.java index e852360..8fde2f3 100644 --- a/Chapter 15 Class Notes/src/StackDemo.java +++ b/Chapter 15 Class Notes/src/StackDemo.java @@ -9,5 +9,26 @@ public class StackDemo { public static void main(String[] args) { + // create a stack of commands + Stack commands = new Stack<>(); + + // push a bunch of commands onto the undo stack + commands.push("Insert 'Hello'"); + commands.push("Insert ','"); + commands.push("Insert ' '"); + commands.push("Insert 'World'"); + commands.push("Insert '?'"); + commands.push("Delete '?'"); + commands.push("Insert '!'"); + + // print the stack; the top of the stack is on the far right + System.out.println(commands); + + // undo the last 4 commands + for(int i = 0; i < 4; i++) + { + String command = commands.pop(); + System.out.println("Undo: " + command); + } } } diff --git a/Chapter 15 Class Notes/src/WordAnalysis.java b/Chapter 15 Class Notes/src/WordAnalysis.java index ffe5bc7..638f786 100644 --- a/Chapter 15 Class Notes/src/WordAnalysis.java +++ b/Chapter 15 Class Notes/src/WordAnalysis.java @@ -13,6 +13,34 @@ public class WordAnalysis public static void main(String[] args) throws FileNotFoundException { + // read the dictionary and the novel + Set dictionaryWords = readWords("src/words"); + Set novelWords = readWords("src/alice30.txt"); + + // 1. print all words that are in the novel but not the dictionary + + // the enhanced for loop works with sets + for(String word : novelWords) + { + if(!dictionaryWords.contains(word)) + { + System.out.println(word); + } + } + + System.out.println("unique words: " + novelWords.size()); + + // 2. print the number of unique words with > 3 letters + Iterator i = novelWords.iterator(); + while(i.hasNext()) + { + if(i.next().length() <= 3) + { + i.remove(); + } + } + + System.out.println("unique words (> 3 letters): " + novelWords.size()); } /** @@ -25,6 +53,25 @@ public static void main(String[] args) public static Set readWords(String filename) throws FileNotFoundException { - return null; + /* + The implementation of the set doesn't matter; so, + store the reference in a variable of type Set + */ + Set words = new HashSet<>(); + Scanner in = new Scanner(new File(filename)); + + // use any character other than a-z or A-Z as delimiters + in.useDelimiter("[^a-zA-Z]+"); + + while(in.hasNext()) + { + /* + adding duplicates to a set is ignored + (so is removing elements that don't exist) + */ + words.add(in.next().toLowerCase()); + } + + return words; } } diff --git a/Chapter 15 Class Notes/src/WorkOrder.java b/Chapter 15 Class Notes/src/WorkOrder.java index 457bb30..02e7bb1 100644 --- a/Chapter 15 Class Notes/src/WorkOrder.java +++ b/Chapter 15 Class Notes/src/WorkOrder.java @@ -25,8 +25,6 @@ public String toString() public int compareTo(Object otherObject) { WorkOrder other = (WorkOrder) otherObject; - if (priority < other.priority) { return -1; } - else if (priority > other.priority) { return 1; } - else { return 0; } + return this.priority - other.priority; } } diff --git a/Chapter 16 Class Notes/src/CircularArrayQueue.java b/Chapter 16 Class Notes/src/CircularArrayQueue.java index 89a6dda..41b7833 100644 --- a/Chapter 16 Class Notes/src/CircularArrayQueue.java +++ b/Chapter 16 Class Notes/src/CircularArrayQueue.java @@ -6,44 +6,61 @@ public class CircularArrayQueue { private Object[] elements; - //private data - - + private int head; + private int tail; + private int currentSize; /** Constructs an empty queue. */ - - - - - + public CircularArrayQueue() + { + final int INITIAL_SIZE = 5; + this.elements = new Object[INITIAL_SIZE]; + this.head = 0; + this.tail = 0; + this.currentSize = 0; + } /** Checks whether this queue is empty. @return true if this queue is empty */ - - - + public boolean empty() + { + return (this.currentSize == 0); + } /** Adds an element to the tail of this queue. @param newElement the element to add */ + public void add(Object newElement) + { + this.growIfNecessary(); - - - + this.currentSize++; + this.elements[this.tail] = newElement; + this.tail++; + this.tail %= this.elements.length; + } /** Removes an element from the head of this queue. @return the removed element */ + public Object remove() + { + if(this.empty()) + { + throw new NoSuchElementException(); + } - - - + Object element = this.elements[this.head]; + this.head = (this.head + 1) % this.elements.length; + this.currentSize--; + return element; + } /** Grows the element array if the current size equals the capacity. diff --git a/Chapter 16 Class Notes/src/LinkedList.java b/Chapter 16 Class Notes/src/LinkedList.java index 11b0b9b..0e2fab6 100644 --- a/Chapter 16 Class Notes/src/LinkedList.java +++ b/Chapter 16 Class Notes/src/LinkedList.java @@ -8,108 +8,198 @@ */ public class LinkedList { - + /* first referes to the first node in this list. If the list + is empty, first is null. */ + private Node first; /** Constructs an empty linked list. */ - - - + public LinkedList() + { + this.first = null; + } /** Returns the first element in the linked list. @return the first element in the linked list */ + public Object getFirst() + { + if(this.first == null) + { + throw new NoSuchElementException(); + } - - + return this.first.data; + } /** Removes the first element in the linked list. @return the removed element */ + public Object removeFirst() + { + if(this.first == null) + { + throw new NoSuchElementException(); + } - - - + Object element = this.first.data; + this.first = this.first.next; + return element; + } /** Adds an element to the front of the linked list. @param element the element to add */ - - - - + public void addFirst(Object element) + { + Node newNode = new Node(); + newNode.data = element; + newNode.next = this.first; + this.first = newNode; + } /** Returns an iterator for iterating through this list. @return an iterator for iterating through this list */ - - - + public ListIterator listIterator() + { + return new LinkedListIterator(); + } //Class Node + static class Node + { + public Object data; + public Node next; + } - class LinkedListIterator //implements ListIterator + class LinkedListIterator implements ListIterator { - //private data - + // private data + private Node position; + private Node previous; + private boolean isAfterNext; /** Constructs an iterator that points to the front of the linked list. */ - + public LinkedListIterator() + { + position = null; + previous = null; + isAfterNext = false; + } /** Moves the iterator past the next element. @return the traversed element */ - - - - + public Object next() + { + if(!hasNext()) + { + throw new NoSuchElementException(); + } + + previous = position; // remember for remove + isAfterNext = true; + + if(position == null) + { + position = first; + } + else + { + position = position.next; + } + + return position.data; + } /** Tests if there is an element after the iterator position. @return true if there is an element after the iterator position */ - + public boolean hasNext() + { + if(position == null) + { + return first != null; + } + else + { + return position.next != null; + } + } /** Adds an element before the iterator position and moves the iterator past the inserted element. @param element the element to add */ - - - - - + public void add(Object element) + { + if(position == null) + { + addFirst(element); + position = first; + } + else + { + Node newNode = new Node(); + newNode.data = element; + newNode.next = position.next; + position.next = newNode; + position = newNode; + } + + isAfterNext = false; + } /** Removes the last traversed element. This method may only be called after a call to the next() method. */ - - - - - - + public void remove() + { + if(!isAfterNext) + { + throw new IllegalStateException(); + } + + if(position == first) + { + removeFirst(); + } + else + { + previous.next = position.next; + } + + position = previous; + isAfterNext = false; + } /** Sets the last traversed element to a different value. @param element the element to set */ - - - - + public void set(Object element) + { + if(!isAfterNext) + { + throw new IllegalStateException(); + } + + position.data = element; + } }//LinkedListIterator }//LinkedList diff --git a/Chapter 16 Class Notes/src/LinkedListStack.java b/Chapter 16 Class Notes/src/LinkedListStack.java index e12647a..1aea384 100644 --- a/Chapter 16 Class Notes/src/LinkedListStack.java +++ b/Chapter 16 Class Notes/src/LinkedListStack.java @@ -20,30 +20,39 @@ public LinkedListStack() * * @param element the element to add */ - - - - - + public void push(Object element) + { + Node newNode = new Node(); + newNode.data = element; + newNode.next = this.first; + this.first = newNode; + } /** Removes the element from the top of the stack. @return the removed element */ - - - - - - - + public Object pop() + { + if(this.empty()) + { + throw new NoSuchElementException(); + } + + Object element = this.first.data; + this.first = this.first.next; + return element; + } /** * Checks whether this stack is empty. * * @return true if the stack is empty */ - + public boolean empty() + { + return (this.first == null); + } static class Node { diff --git a/Chapter 16 Class Notes/src/ListDemo.java b/Chapter 16 Class Notes/src/ListDemo.java index 36dcfe9..c79b0c7 100644 --- a/Chapter 16 Class Notes/src/ListDemo.java +++ b/Chapter 16 Class Notes/src/ListDemo.java @@ -5,5 +5,31 @@ public class ListDemo { public static void main(String[] args) { + // create a linked list and add names to it + LinkedList staff = new LinkedList(); + staff.addFirst("Tom"); + staff.addFirst("Romeo"); + staff.addFirst("Harry"); + staff.addFirst("Diana"); + + ListIterator iterator = staff.listIterator(); // |DHRT + iterator.next(); // D|HRT + iterator.next(); // DH|RT + + // add more elements after the second element + iterator.add("Juliet"); // DHJ|RT + iterator.add("Maria"); // DHJM|RT + + // remove Romeo + iterator.next(); // DHJMR|T + iterator.remove(); // DHJM|T + + // print all elements + iterator = staff.listIterator(); + while(iterator.hasNext()) + { + System.out.print(iterator.next() + " "); + } + System.out.println(); } } diff --git a/Chapter 16 Class Notes/src/QueueDemo.java b/Chapter 16 Class Notes/src/QueueDemo.java index a1aa0db..9f0aab7 100644 --- a/Chapter 16 Class Notes/src/QueueDemo.java +++ b/Chapter 16 Class Notes/src/QueueDemo.java @@ -2,5 +2,20 @@ public class QueueDemo { public static void main(String[] args) { + CircularArrayQueue queue = new CircularArrayQueue(); + + queue.add("Tom"); + queue.add("Diana"); + queue.add("Harry"); + System.out.println(queue.remove()); // remove Tom + queue.add("Romeo"); + System.out.println(queue.remove()); // remove Diana + queue.add("Juliet"); + queue.add("Maria"); + + while(!queue.empty()) + { + System.out.println(queue.remove()); + } } } diff --git a/Chapter 16 Class Notes/src/StackDemo.java b/Chapter 16 Class Notes/src/StackDemo.java index 32fa99f..f969f8e 100644 --- a/Chapter 16 Class Notes/src/StackDemo.java +++ b/Chapter 16 Class Notes/src/StackDemo.java @@ -2,5 +2,17 @@ public class StackDemo { public static void main(String[] args) { + LinkedListStack stack = new LinkedListStack(); + + stack.push("Tom"); + stack.push("Diana"); + stack.push("Harry"); + + while(!stack.empty()) + { + System.out.println(stack.pop()); + } + + System.out.println("Expected: Harry Diana Tom"); } } diff --git a/Chapter 17 Class Notes/src/BinarySearchTree.java b/Chapter 17 Class Notes/src/BinarySearchTree.java index 6720a31..ecae3eb 100644 --- a/Chapter 17 Class Notes/src/BinarySearchTree.java +++ b/Chapter 17 Class Notes/src/BinarySearchTree.java @@ -12,7 +12,7 @@ public class BinarySearchTree */ public BinarySearchTree() { - + this.root = null; } /** @@ -21,7 +21,19 @@ public BinarySearchTree() */ public void add(Comparable obj) { + Node newNode = new Node(); + newNode.data = obj; + newNode.left = null; + newNode.right = null; + if(this.root == null) + { + this.root = newNode; + } + else + { + this.root.addNode(newNode); + } } /** @@ -31,6 +43,25 @@ public void add(Comparable obj) */ public boolean find(Comparable obj) { + Node current = this.root; + + while(current != null) + { + int diff = obj.compareTo(current.data); + if(diff == 0) + { + return true; + } + else if(diff < 0) + { + current = current.left; + } + else + { + current = current.right; + } + } + return false; } @@ -41,7 +72,91 @@ public boolean find(Comparable obj) */ public void remove(Comparable obj) { + Node toBeRemoved = this.root; + Node parent = null; + boolean found = false; + + while(!found && toBeRemoved != null) + { + int diff = obj.compareTo(toBeRemoved.data); + if(diff == 0) + { + found = true; + } + else + { + parent = toBeRemoved; + if(diff < 0) + { + toBeRemoved = toBeRemoved.left; + } + else + { + toBeRemoved = toBeRemoved.right; + } + } + } + + if(!found) + { + return; + } + + // if one of the children is empty, use the other child (Case 1 & 2) + if(toBeRemoved.left == null || toBeRemoved.right == null) + { + Node newChild; + + if(toBeRemoved.left == null) + { + newChild = toBeRemoved.right; + } + else + { + newChild = toBeRemoved.left; + } + + if(parent == null) + { + this.root = newChild; + } + else if(parent.left == toBeRemoved) + { + parent.left = newChild; + } + else + { + parent.right = newChild; + } + return; + } + + // neither subtree of the node to be removed is empty (Case 3) + + // find the least element of the right subtree + Node leastParent = toBeRemoved; + Node least = toBeRemoved.right; + while(least.left != null) + { + leastParent = least; + least = least.left; + } + + // least refers to the least child in the right subtree + + // move the data + toBeRemoved.data = least.data; + + // unlink the least child + if(leastParent == toBeRemoved) + { + leastParent.right = least.right; + } + else + { + leastParent.left =least.right; + } } /** @@ -49,7 +164,8 @@ public void remove(Comparable obj) */ public void print() { - + print(this.root); + System.out.println(); } /** @@ -58,7 +174,13 @@ public void print() */ private static void print(Node parent) { - + if(parent == null) + { + return; + } + print(parent.left); + System.out.print(parent.data + " "); + print(parent.right); } /** @@ -67,7 +189,9 @@ private static void print(Node parent) */ static class Node { - + public Comparable data; + public Node left; + public Node right; /** Inserts a new node as a descendant of this node. @@ -75,7 +199,29 @@ static class Node */ public void addNode(Node newNode) { - + int diff = newNode.data.compareTo(data); + if(diff < 0) + { + if(left == null) + { + left = newNode; + } + else + { + left.addNode(newNode); + } + } + else if(diff > 0) + { + if(right == null) + { + right = newNode; + } + else + { + right.addNode(newNode); + } + } } } } diff --git a/Chapter 17 Class Notes/src/BinaryTree.java b/Chapter 17 Class Notes/src/BinaryTree.java index a732909..5a0df29 100644 --- a/Chapter 17 Class Notes/src/BinaryTree.java +++ b/Chapter 17 Class Notes/src/BinaryTree.java @@ -10,7 +10,7 @@ public class BinaryTree */ public BinaryTree() { - + this.root = null; } /** @@ -19,7 +19,10 @@ public BinaryTree() */ public BinaryTree(Object rootData) { - + this.root = new Node(); + this.root.data = rootData; + this.root.left = null; + this.root.right = null; } /** @@ -30,12 +33,16 @@ public BinaryTree(Object rootData) */ public BinaryTree(Object rootData, BinaryTree left, BinaryTree right) { - + this(rootData); + this.root.left = left.root; + this.root.right = right.root; } static class Node { - + public Object data; + public Node left; + public Node right; } /** @@ -45,7 +52,14 @@ static class Node */ private static int height(Node n) { - return 0; + if(n == null) + { + return 0; + } + else + { + return 1 + Math.max(BinaryTree.height(n.left), BinaryTree.height(n.right)); + } } /** @@ -54,7 +68,7 @@ private static int height(Node n) */ public int height() { - return 0; + return BinaryTree.height(this.root); } /** @@ -63,7 +77,7 @@ public int height() */ public boolean isEmpty() { - return false; + return (this.root == null); } /** @@ -72,7 +86,7 @@ public boolean isEmpty() */ public Object data() { - return null; + return this.root.data; } /** @@ -81,7 +95,9 @@ public Object data() */ public BinaryTree left() { - return null; + BinaryTree subtree = new BinaryTree(); + subtree.root = this.root.left; + return subtree; } /** @@ -90,6 +106,8 @@ public BinaryTree left() */ public BinaryTree right() { - return null; + BinaryTree subtree = new BinaryTree(); + subtree.root = this.root.right; + return subtree; } } diff --git a/Chapter 17 Class Notes/src/TraversalDemo.java b/Chapter 17 Class Notes/src/TraversalDemo.java index 827e5af..155a553 100644 --- a/Chapter 17 Class Notes/src/TraversalDemo.java +++ b/Chapter 17 Class Notes/src/TraversalDemo.java @@ -16,7 +16,7 @@ public static void main(String[] args) t2.addSubtree(t4); // Count short names with visitor - /*class ShortNameCounter implements Tree.Visitor + class ShortNameCounter implements Tree.Visitor { public int counter = 0; public void visit(Object data) @@ -29,6 +29,6 @@ public void visit(Object data) ShortNameCounter v = new ShortNameCounter(); t1.preorder(v); - System.out.println("Short names: " + v.counter); */ + System.out.println("Short names: " + v.counter); } } diff --git a/Chapter 17 Class Notes/src/Tree.java b/Chapter 17 Class Notes/src/Tree.java index a856e43..9be29b1 100644 --- a/Chapter 17 Class Notes/src/Tree.java +++ b/Chapter 17 Class Notes/src/Tree.java @@ -6,10 +6,12 @@ */ public class Tree { + private Node root; static class Node { - + public Object data; + public List children; /** Computes the size of the subtree whose root is this node. @@ -17,7 +19,13 @@ static class Node */ public int size() { - return 0; + int sum = 1; + for(Node child : this.children) + { + sum += child.size(); + } + + return sum; } } @@ -27,7 +35,9 @@ public int size() */ public Tree(Object rootData) { - + this.root = new Node(); + this.root.data = rootData; + this.root.children = new ArrayList<>(); } /** @@ -35,7 +45,7 @@ public Tree(Object rootData) */ public void addSubtree(Tree subtree) { - + this.root.children.add(subtree.root); } /** @@ -44,8 +54,50 @@ public void addSubtree(Tree subtree) */ public int size() { - return 0; + return this.root.size(); } // Additional methods will be added in later sections. + + /** + * A visitor whose visit method is called for each visited node during + * a tree traversal. + */ + public interface Visitor + { + /** + * This method is called for each visited node. + * @param data the data of the node being visited + */ + void visit(Object data); + } + + /** + * Traverses this tree in preorder. + * @param v the visitor to be invoked at each node + */ + public void preorder(Visitor v) + { + Tree.preorder(this.root, v); + } + + /** + * Traverses the tree with a given root in preorder + * @param n the root of the tree to traverse + * @param v the visitor to be invoked at each node + */ + private static void preorder(Node n, Visitor v) + { + if(n == null) + { + return; + } + + v.visit(n.data); + + for(Node child : n.children) + { + Tree.preorder(child, v); + } + } }