|
Comp201: Principles of Object-Oriented Programming
|
Pledge of Honor |
1. 15 pts + 5 pts extra credit | 2. 20 pts | 3. 25 pts | 4. 20 pts | 5. 20 pts + 5 pts extra credit | Total 100 pts + 10 pts extra credit |
Using the SmartArray system (see lab14), implement the method remDup that removes all duplicate elements in the SmartArray. Two objects, x and y, are defined as being duplicates if x.equals(y) returns true.
SmartArray remDup()-- For each element, remove any duplicates of it in the array.
You may assume that the SmartArray does not contain any null values in its apparent array.
5 pts extra credit if you implement your algorithm using a variable shift mechanism (use remDupBetter) to minimize the number of traversals of the array. You may implement both remDupBetter and remDup if you are not sure if one technique will work. You are not required to have both implementations.
This is very similar to the RAC presented in class except for one very important difference: the IRAContainer.isEmpty() method is absent.
A RAC behaves differently when it is empty or non-empty. Therefore, it makes sense for a RAC (IRAContainer) to be able to accept a two-case visitor.
a) (5 pts) Write IRACVisitor interface for visitors to the above RAC. A skeleton file for the class has been provided.
b) (10 pts) Write the code for the execute method of LRSRAContainer (ALRSFactory$LRSRAContainer in the above UML class diagram which does not show the execute method).
c) (5 pts) Write an IRACVisitor called rac.visitor.IsEmpty that returns Boolean.TRUE if the RAC is empty and Boolean.FALSE if it is non-empty. A skeleton file for IsEmpty has been provided as well as a test file.
Tip: To access the outer LRSRAContainer object from within an anonymous inner class inside a LRSRAContainer, use the syntax LRSRAContainer.this.
NO CONDITIONALS ARE ALLOWED IN YOUR SOLUTION! Think simply and directly!
Write a BiTree visitor, called CountGreaterThan, for execution on a binary search tree (BST) that counts all objects greater than a given key.
Finally, to receive full credit, your visitor must visit the fewest possible
nodes.
The brs package along with some of the visitors developed in class has been provided, including a skeleton of the CountGreaterThan class.
A test file has been provided.
Recommendation: Take a piece of paper and draw a tree on it, tracing what you want the algorithm to do under various circumstances. Be sure to consider all possibilities!
Consider the following technique for sorting called a "Sink Sort" . (See the demo)
Initially: 4 5 1 3 2 ("top" is on the left at index 0, "bottom" is on the right at index 4)
Split all the array into one element arrays: 4 5 1 3 2
2 is already sorted: 4 5 1 3 2
Sink 3 until at right of 2: 4 5 1 2 3
Sink 1-already there : 4 5 1 2 3
Sink 5 until at right of 3: 4 1 5 2 3
4 1 2 5 3
4 1 2 3 5
Sink 4 until at right of 3: 1 4 2 3 5
1 2 4 3 5
1 2 3 4 5
Basically the idea is that the next number is "sunk" by swapping places with its adjacent number on the right until it is smaller than the number to its right. According to Merritt's split-sort-sort-join model of sorting, Sink sort is an easy split/hard join algorithm. The code for split is simply:
protected int split(Object[] A, int lo, int hi){
return (lo + 1);
}
Write the code for the join method of Sink sort as described in the above.
/**
* Given A[lo..s-1] and A[s..hi] sorted,
* merges the two sub-arrays so that A[lo..hi] is sorted.
* Here s == lo + 1 (see split).
* The merge should be done in such a way that the numbers
in A[lo..s-1]
* sink by swapping places with their adjacent right (higher
indexed) neighbors until each
* is smaller than the number to its right, or until hi is
encountered.
*/
protected void join(Object[] A, int lo, int s, int hi){
// Students to write code.
}
One very interesting application of binary trees and arrays is to implement a binary tree as an array. Such a marriage would imbue the binary tree with the speed and random access capabilities of an array, something that could be quite useful if the binary tree was a binary search tree, or something of that ilk (stay tuned next semester!). Of course, it would also come with the price that an array pays, namely the inability to mutate its structure. But let's forge ahead anyway...
Consider the following binary tree:
A |_B | |_D | | |_[] | | |_[] | |_E | |_[] | |_[] |_C |_F | |_[] | |_[] |_G |_[] |_[]
We can put this tree into an array as such: [A, B, C, D, E, F, G]
This ordering technique has the following interesting properties:
Given an index of the parent (root) node, idxRoot,
- the index of the left subtree is idxLeft = 2*idxRoot + 1 (e.g. A->B, B->D, C->F)
- the index of the right subtree is idxRight = 2*idxRoot + 2 (e.g. A->C, B->E, C->G)
Convince yourself this is true for any element of the binary tree, no matter how big it is.
If the tree is not "full" then we simpy leave nulls in the array:
becomesA |_B | |_[] | |_E | |_[] | |_[] |_C |_F | |_[] | |_[] |_[]
[A, B, C, null, E, F,null]
See the test class for more examples.
The array must therefore be sized for the worst case scenario: Given the maximum height of the binary tree, hMax, then the required size of the array is (int)Math.pow(2, hMax)-1
Write an IVisitor called BRS2Array that returns a new array of Objects filled with the elements of the host BiTree where the elements are located in the above ordering scheme.
Notes:
5 pts Extra Credit: Write a the body of util.ArrayUtil.equals() such that it returns true if the two given Object arrays are equal and returns false if they are not. To test your code, substitute in the use of this static method in the body of Test_BRS2Array.isEqual() and re-run the test cases.
Last Revised Thursday, 03-Jun-2010 09:50:18 CDT
©2004 Stephen Wong and Dung Nguyen