The exam has 8 problems. Problems 1-5 are programming problems; problems 6-8 are written problems. The number of points for each problem appears in brackets next to the problem. There are 100 points total on the exam. All programming problems contribute to the same applet, and you can do them in any order, though they appear roughly in order of increasing difficulty.

The exam is open book in the sense that you can consult any books,
handouts, or notes from this class to solve the problems. You may
also follow the links from the course page and this exam 2 page to
directly linked materials, e.g., the Java API and linked Wikipedia pages.
However, **you may not do any web searches**, for instance to find answers
on online discussion boards. You **may not look at any code, except**
for the code examples from the course web page and the textbook.
Also, you may not
consult material or solutions from previous semesters
or try to gain access to the source code for sample applets. I am the only
person you may talk to about the exam. **You may not consult or
collaborate with other students or tutors**. I will clarify the
problems if you have trouble understanding them, but because this is
an exam, I cannot help you solve the problems. If you are stuck, definitely
come see me -- I can at least give general problem-solving advice.

Please be very careful to protect your work from the access of others.

- Your name must appear at the top
- All text must be typed
- You may only include photos of your tree drawings
- The file must be saved in PDF format
- The file size must be less than 2MB (do a Web search for "reducing file size PDF" or "save Word as PDF small file size" to find out how)

The deadline for both submissions Wednesday 11/21 at 11:59pm. This is a hard deadline. You cannot turn in the exam later than this time, and you cannot use one of your 24 h extensions. Even if you are not finished with the exam by this time, you should turn in what you have, so that I can award partial credit. If a program does not work completely, it would be helpful if you included comments that describe what aspects of your program do and don't work. Be sure that your code at least compiles, otherwise you will likely receive a failing grade on the programming portion.

K-d Trees

The programming problems on this exam involve K-d trees a data structure used to organize points in K dimensions. Here's a Wikipedia page, which you may look at, including the code listed on that page (but recall any other code on the web is off limits).

In this exam (and the description below), we only consider K=2 dimensions, a set of points in the 2D plane.

A K-d tree is a binary search tree. Each node stores a 2D point (x, y), which serves as a "splitting point" for the remaining points in the subtrees. Either the x or y coordinate is used for splitting, alternating by level. At the root (level 0) we use the x coordinate, at level 1 the y coordinate, at level 2 the x-coordinate again, and so on. (For higher-dimensional K-d trees, one rotates through all dimensions by level, e.g., x, y, z, x, y, z, ...)

Here's a snapshot of the exam 2 applet in action, with hand-drawn annotations:

On the left we see an arrangement of four points in the plane as well as their splitting lines; on the right we see the corresponding binary tree. X-nodes are shown in blue, y-nodes in red. The green hand-drawn arrows indicate how nodes on the right correspond with points on the left. The root node corresponds to the point with coordinates (66, 118). It is an x-node (dark blue), thus all points in the left subtree have x-coordinates <= 66, and all points in the right subtree have x-coordinates >= 66. On the left, this is visualized with the dark blue vertical line extending all the way from the top to the bottom.

Now, consider the children of the root node on level 1, which are
y-nodes (dark red). For instance, the right child corresponds to the
point with coordinates (217, 198). Since it is a y-node, all points
in the left subtree have y-coordinates <= 198 (here there aren't
any), and all points in the right subtree have y-coordinates >=
198. Again, on the left this is visualized with lines, this time dark
red and horizontal; note that they extend from the edges to vertical
"root line". Note that for y-nodes, the left subtree (with smaller y
values) corresponds to the region *above* the line, and the right
subtree to the region *below* the line.

Next, on level 2 we only have one node, an x-node again, and its (blue) vertical splitting line ends at the horizontal "parent line".

Play with the sample applet below (or with this bigger version) to get a feel for how the arrangement of points on the left corresponds to the tree on the right. Problems 1-5 on this exam involve adding code to a skeleton file to create an applet that functions like the one shown here. Additional information on how the applet functions is given in the problem descriptions.

Recall that you can run any applet in the appletviewer by providing the URL of the page containing the applet. To do so for the sample exam applet, type

All files required for this exam are contained in the fileappletviewer http://www.cs.middlebury.edu/~schar/courses/cs201-f18/hw/exam2/

KdTree.java - the definition of the K-d tree KdTreeApplet.java - the actual applet * KdTreeOps.java - operations on K-d trees Point.java - a simple 2D point class PointCanvas.java - the left portion of the applet, rendering points and lines TreeCanvas.java - the right portion of the applet, rendering the tree kdapp.html - an html file to run the appletThe only file you have to modify is marked with a star. However, you should study the other files as well, in particular

Import the `exam2` directory into Eclipse as usual.
The code provided compiles and runs. You can run it from within Eclipse
by opening `KdTreeApplet.java` and
selecting "Run As -> Java Applet",
or from the command line using:

javac KdTreeApplet.java appletviewer kdapp.htmlAfter running it once from Eclipse, I suggest you change the applet size to width 1000 and height 600 (Run -> Run Configurations -> Parameter tab).

Start by adding your name to the top `KdTreeOps.java` (expand
the comment at the top). Initially, many parts of the applet are not
yet functional. As you are completing the programming problems, more
functionality will be added piece by piece, which allows you to test
your code for each problem thoroughly before moving on to the next
problem. **Be sure your code compiles at all times!**

Problem 1 [10]: Counting nodes

Once your methods work, the node counts displayed above the tree should be correct.

Problem 2 [10]: Checking whether the tree is symmetric

Once your methods work, the text displayed above the tree should correctly indicate whether the tree is symmetric.

Problem 3 [15]: Computing the width of trees

We compute the width of a tree by measuring the width of an (imaginary) picture of the tree which is drawn according to the following rules: All nodes are drawn as circles with radius 1. To draw a tree, we draw the circle for the root, and then each of the two subtrees below such that they touch the vertical line through the center of the root circle (from the left and the right, respectively). Some trees and their widths are shown below:

- The width of an empty tree is 0
- The width of a leaf is 2
- The width of a tree with one child is the width of the child + 1 (= width of half the root)
- The width of a tree with two children is the sum of the widths of its children

- The left width of an empty tree is 0
- The left width of a leaf is 1
- The left width of a tree with a left child is the width of the child

Note that some of the above rules are redundant. Try to define the each function in terms of the others as succinctly as possible.

Once your methods work, the tree drawn with "variable" drawing style
should match the way it is drawn in the sample applet. (Note that the
drawing code, which you can find in `TreeCanvas.java`,
multiplies the values returned by your functions with radius of the
node circles to determine the proper spacing.

Problem 4 [15]: Drawing the splitting lines

Once your methods work, the drawing on the left side of applet should match that of the sample applet.

Problem 5 [15]: Rebuilding a balanced tree

- Base case: if start >= end, return null.
- Else, sort the vector of points from index start .. end-1 by the appropriate coordinate (alternatingly x or y, starting with x at the root);
- compute the middle index mid = (start + end) / 2;
- select the point at index mid to be stored in the current node (which has the median x or y coordinate);
- recursively build subtrees from the front half (start .. mid-1) and the rear half (mid+1 .. end-1) of the vector;
- return a new node with the selected mid point and the two recursive results.

Once your methods work, clicking the "Rebuild" button should balance the tree and change the arrangement of the splitting lines, but should not affect the number and location of the points. Again, compare with the behavior of the sample applet to make sure your methods work correctly.

Problem 6 [12]: Complexity of tree and heap operations

- Finding the smallest number in a skew heap of N integers
- Adding an new number to a complete heap of N integers
- Finding the largest number in a complete heap of N integers
- Finding the smallest number in a
*complete*binary search tree containing N integers - Finding the largest number in an
*arbitrary*binary search tree containing N integers - Checking whether a given number is contained in an AVL tree containing N integers

Problem 7 [13]: Tree drawing

- Draw all complete heaps containing the five values 1, 2, 3, 3, 4.
(Note the duplicate 3!) How many are there?
- Draw all complete binary search trees containing the six values
1, 2, 3, 4, 5, 6. How many are there?
- Draw all full, ordered 2-3 trees containing the eight values
1, 2, 3, 4, 5, 6, 7, 8. How many are there?
- Draw all ordered AVL (i.e., balanced) trees containing the five values 1, 2, 3, 4, 5. How many are there?

Problem 8 [10]: Tree traversals

public static void levelOrderWrite(IntTree t) { // prints out the contents of the tree t in level order Queue<IntTree> q = new QueueList<IntTree>(); q.add(t); while (!q.isEmpty()) { IntTree node = q.remove(); if (!isEmpty(node)) { System.out.print(" " + value(node)); q.add(left(node)); q.add(right(node)); } } System.out.println(); }What would happen if you replaced the queue with a stack? List the order in which the values of the following tree would get printed:

In general, would all nodes in the tree get printed? If yes, in what order? Justify your answer. (You are welcome to try it out, but you'll have to explain your findings - simply stating what happens is not enough.) Include your answer with your written submission.

Good Luck!