|
Comp201: Principles of Object-Oriented Programming I
|
Check the time stamp at the bottom of the page to be sure that you have the latest version with any typographical corrections!
Pledge of Honor |
1. 15 pts | 2. 15 pts | 3.a 10 pts | 3.b 5 pts | 3.c 15 pts | 4.a 15 pts | 4.b 10 pts | 4.c 15 pts | 4.d
15 pts extra |
Total: 100 pts
+ 15 pts extra |
You must supply both the electronic and paper copies of your exam in order to for you exam to be graded!
In general, since we are ignoring the "generics" features of Java, DrJava will occasionally complain with an "unchecked type warning" (or something similar). Ignore these warnings -- they can be permanently suppressed by un-checking the appropriate box under "Preferences/Compiler Options" in DrJava.)
Since you are such experts now at writing algorithms on lists to determine "deep" equality (recursive equality that checks the entire list), let's move on to the same function on binary trees.
Write an IVisitor algorithm called BRSEquals that will take another BiTree as its input and return true if all the corresponding data elements in the host and input trees are equal (as determined by their equals method) and returns false otherwise.
Now you're on a roll! So let's move on to array equality. There's a lot lost in going to arrays, namely polymorphism and intelligence. Arrays cannot support visitors, so we have to write a separate utility class that takes in the arrays to be processed as input parameters. Arrays have no internal sense of being empty or non-empty and not recursive data structures, so there things to be checked that in lists and trees are automatically taken care of by polymorphism.
Write a class called ArrayUtils with a method called isEqual that takes in two arrays of Objects (i.e. type Object[]) and returns true if all the corresponding elements in the arrays are equal (as determined by their equals method). false should be returned if any corresponding elements are not equal or the arrays are of different length.
The following is a proposed algorithm (by a student) to delete the root of a binary search tree of type BiTree.
3.a. (10 pts) Write a BiTree visitor called RemRootBST to remove the root of a binary search tree as described by the above algorithm. The stub code in in the package brs.visitor of the provided project (prob3).
3.b. (5 pts) Compare the algorithm in 3.a against BSTDeleter, the algorithm to remove an element from a binary search tree given in lecture 36: http://www.owlnet.rice.edu/~comp201/06-spring/lectures/lec36/. Discuss the pros and cons. Write your answer as comments at the top of the visitor code.
3.c (15 pts) Consider a binary search tree, specifically, the implementation presented in lecture using class BiTree. Write a BiTreevisitor named BSTFindNext that returns the BiTree object that is the next largest object relative to the visitor's input. The visitor's input may or may not be in the binary search tree. If there is no next larger element, return an empty BiTree. The stub code in in the package brs.visitor.
Examples: Consider the following binary search tree containing Integer.
57 / \ 33 78 / \ 63 91 / \ 59 71 / 70
Let BiTree bst be the above binary search tree and bstfindnext be an instance of BSTFindNext.
The code for the above tree model is in the package tree of the supplied code (prob4).
Examples: Using horizontal lines to denote right sibling links and (slanted) vertical lines to denote left-most child links, and the letter ‘e’ to denote an empty n-ary tree, the following illustrates various n-ary trees and their corresponding leftmost child - right sibling representations. For simplicity, the empty binary trees at the end of leaf nodes on the binary tree have been omitted.
n-ary Tree | Leftmost Child - Right Sibling | Java Code |
empty tree | e | Tree t = new Tree(); |
57 |
57 -- e / e |
Tree t = new Tree(); t.insertRoot(57); |
57 or 57 or 57 | / \ / \ 33 33 e e 33 |
57 -- e / 33 -- e / e |
Tree t = new Tree(); t.insertRoot(57); Tree lmc = new Tree(); lmc.insertRoot(33); t.set_leftMostChild(lmc); |
57 / \ 33 78 |
57 -- e / 33 -- 78 -- e / / e e |
Tree t = new Tree(); t.insertRoot(57); Tree lmc = t.get_leftMostChild(); lmc.insertRoot(33); lmc.get_rightSibling().insertRoot(78); |
57 / | \ 33 78 12 / \ 63 19 / \ / \ 42 e e 6 |
57 -- e / 33 -- 78 -- 12 -- e / / e 63 ----- 19 -- e / / 42 -- e 6 -- e / / e e
|
Tree t = new Tree(); t.insertRoot(57); Tree lmc = t.get_leftMostChild(); lmc.insertRoot(33); lmc.get_rightSibling().insertRoot(78); // etc... |
4.a. (15 pts) Write an ITreeVis algorithm called TreeEqual that will take another Tree as its input and return true if all the corresponding data elements in the host and input trees are equal (as determined by their equals method) and returns false otherwise. The stub code for TreeEqual is in the package tree.visitor. Hint: this algorithm is very similar to the algorithm in problem 1. You may need to write anonymous helper visitors here.
4.b. (10 pts) Write a JUnit test class called TestTreeEqual that tests the visitor TreeEqual in 3.a. The test code must cover at least the following cases for the host:
You are to figure out what the various input Trees should be to thoroughly test the visitor. The stub code for TestTreeEqual is in package tree.visitor.test.
4.c. (15 pts) Like the case of the binary tree structure BiTree, we allow removal of the root only when the leftmost child is empty or when the right sibling is empty. In the empty leftmost child case, when we remove the root node, the tree node is replaced by the node of its right sibling. In other words, the tree mutates to become its original right sibling. In the empty right sibling case, when we remove the root node, the tree node is replaced by its leftmost child. In other words, the tree mutates to become its original leftmost child. The root node cannot be removed when both leftmost child and right sibling are non-empty. A IllegalStateException should be thrown in this case. Below are some examples to illustrate the root removal specification.
Tree t | Resulting t after t.removeRoot() |
empty | NoSuchElementException thrown |
57 -- e / e |
empty |
33 -- 78 -- 12 -- e / / e 63 ----- 19 -- e / / 42 -- e 6 -- e / / e e
|
78 -- 12 -- e / 63 ----- 19 -- e / / 42 -- e 6 -- e / / e e |
57 -- e / 33 -- 78 -- 12 -- e / / e 63 ----- 19 -- e / / 42 -- e 6 -- e / / e e |
33 -- 78 -- 12 -- e / / e 63 ----- 19 -- e / / 42 -- e 6 -- e / / e e |
78 -- 12 -- e / 63 ----- 19 -- e / / 42 -- e 6 -- e / / e e |
IllegalStateException thrown |
Complete the code for the method removeRoot() in NonEmpty.java to implement the above specification.
4.d. (15 pts extra) Write a BiTree visitor called MakeTree that builds and returns an equivalent n-ary Tree for the BiTree host. For examples,
BiTree host | Equivalent Tree |
empty | empty |
57 / \ e e |
57 -- e / e |
57 / \ 33 e |
57 -- e / 33 -- e / e |
57 / \ e 78 |
57 -- e / 78 -- e / e |
57 / \ 33 78 |
57 -- e / 33 -- 78 -- e / / e e |
57 / \ 33 78 / \ 63 19 / \ / \ 42 e e 6 |
57 -- e / 33 -- 78 --- e / / e 63 ----- 19 -- e / / 42 -- e 6 -- e / / e e |
57 / \ 33 78 / \ 89 23 / \ / \ 18 e e 99 |
57 -- e / 33 ---------------- 78 --- e / / 89 ----- 23 -- e e / / 18 -- e 99 -- e / / e e |
The stub code for MakeTree is in the package brs.visitor. Feel free to write additional helper visitors if needed.
Hints (compare these hints with the above diagrams):
Last Revised Thursday, 03-Jun-2010 09:50:18 CDT
©2006 Stephen Wong and Dung Nguyen