## Fall 2010

1. (14 points)-2 points each For each of the following questions choose the best data structure to use from the below list. You may have to use the same answer for more than one question:
```Hash Table				Linked List		Array
Binary Search Tree (unbalanced)		AVL Tree		Stack
Heap
```
1. Heap You are writing a waiting list application for the door person at a popular night club. As each party of customers arrive, the door person assigns the party a priority number based on the party's perceived desirability in the club. The door person then adds them to your computerized wait list and when space becomes available, the door person admits the next party with the lowest priority number. What data structure should you use to implement the wait list?

2. Hash Table You are writing an address book application. A user should be able to insert (name, address) pairs into the address book, lookup addresses by entering a name, and delete (name,address) pairs from the address book. These are the only operations that your address book must support. What data structure should you use to implement the address book?

3. Array You are reading input lines from a file. Each input line contains a student name and a midterm grade. With each student you want to store the set of midterms associated with that student. For each student, the midterms should be stored in the order in which they are read. You know that each student will have 3 midterms. What data structure should you use to store the midterms for each student?

4. Stack When computing taxes on selling the shares of a stock, you are allowed to select a last-in, first-out (LIFO) option, which means that the last shares that you purchased are the first ones that you consider sold. If you have a computer application that reads a set of stock transactions, what data structure should you use to store the stock transactions in order to facilitate implementing the LIFO option?

5. Binary Search Tree You want to read a file that contains the names of contestants on America's Next Top Model and the number of votes that they received. You want to be able to be able to perform a variety of range queries, such as finding the top 5 contestants, the bottom 5 contests, or the number of contestants receiving between x and y votes. What data structure should you use, assuming that you feel the vote totals will be presented in a random order?

6. You are reading the names of golfers and their scores from a file. Each input line contains the name of a golfer, the golf course where the round was played, and the score for that round. For each golfer you want to store the information for each round played by that golfer. There is no limit to the number of rounds per golfer. After reading the input, the user should be able to query for a golfer and obtain the golferâ€™s average score and a print out of the rounds played by that golfer. The insertion operation and the query operation are the only operations performed on the data.

1. Hash Table What data structure should be used to store the golfers?

2. Linked List For each golfer, what data structure should be used to store the information about the golfer's rounds? You should assume that each round has one record and the rounds may be stored in any order.

2. (4 points) For the following problem, give a one line statement that achieves the desired outcome: Divide an integer, n, by 16 and assign the result to n. Your answer must use a bit expression, not division.

n = n >> 4;

1. Deduct one point for having the arrows point the wrong way.
2. Deduct 2 points for having a number other than 4.
3. Deduct 4 points for using the division operator

3. (10 points)-2 points each Show the hash table that results if the integers 22, 34, 11, 21, 44 are inserted into the following hash table using:
• quadratic probing, and
• the hash function h(k) = k % 11
```           -----------------------
0    | 22                  |
-----------------------
1	   | 34                  |
-----------------------
2    |                     |
-----------------------
3	   |                     |
-----------------------
4	   | 11                  |
-----------------------
5	   |                     |
-----------------------
6	   |                     |
-----------------------
7	   |                     |
-----------------------
8	   |                     |
-----------------------
9	   | 44                  |
-----------------------
10   | 21                  |
-----------------------

```
4. (10 points)-1 point each Show the hash table that results if the integers 51, 46, 23, 81, 21, 38, 30, 44, 56, and 69 are inserted into the following hash table using:
• separate chaining, and
• the hash function h(k) = k % 7
You should append integers to the end of your lists.
```           -----------------------
0    |                     | -> 21 -> 56
-----------------------
1	   |                     |
-----------------------
2    |                     | -> 51 -> 23 -> 30 -> 44
-----------------------
3	   |                     | -> 38
-----------------------
4	   |                     | -> 46 -> 81
-----------------------
5	   |                     |
-----------------------
6	   |                     | -> 69
-----------------------
```

5. (4 points)-2 points each Based on the discussion in class about load factor considerations and the best types of numbers to choose for hash table sizes, what table size should you choose for a data set that contains 14 elements if you use:

1. separate chaining: 17-The first prime number greater than the data set size
2. linear probing: 29-The first prime number greater than twice the data set size

6. (4 points) Suppose you are giving the following type declaration:
```typedef struct {
int salary;
char *name;
} employee;
```
Declare a pointer variable named workers that is a pointer to an array of employee pointers. Then malloc an array of 20 employee pointers and assign the result to workers. You can combine the declaration and the malloc into a single statement if you wish.

employee **workers = (employee **)malloc(sizeof(employee *)*20);

1. 1 point: for the declaration
2. 1 point: for the cast
3. 1 point: for the sizeof
4. 1 point: for the multiplication by 20

7. (4 points) Write a statement that declares a pointer variable named deleteEntry that points to a function that returns a bool and that takes as a parameter a pointer to a void *.

bool (*deleteEntry)(void *);

1. 1 point for the bool
2. 2 points for the (*deleteEntry)-assign partial credit if something is missing, such as the parentheses or the *
3. 1 point for the (void *)-(void **) is okay

8. (8 points) Show the binary search tree that results if 150 is deleted from the tree below:
```                           ---185---
/         \
150         200
/  \           \
100  175         300
/     /
90   160
\
170
```
To delete 150 we must find the smallest child in its right subtree, which is 160. 160 will get promoted to 150's spot but first we must delete 160 from the tree. When we delete 160 its right child gets promoted to 175's original spot as a descendent of 175. The final tree becomes:
```                           ---185---
/         \
160         200
/  \           \
100  175         300
/     /
90   170
```
1. 5 points: 160 gets promoted to replace 150
2. 3 points: 170 gets promoted to become the left child of 175

9. (6 points) Show the result of doing a single left rotation about the node 400. Do not worry if the rotation increases the height of the tree. All I care about is whether you know how to perform a rotation.
```                            -300-
/     \
175	 400
\     /
250 350
```
The left rotation will cause 300 to become a left child of 400. In so doing the left subtree rooted at 400 will become an orphan because 300 is taking its place as 400's left child. Therefore 300 adopts 350 as its right child while keeping 175 as its left child. Note that it is ok for 300 to adopt 350 as its right subtree because 350 is greater than 300:
```                         	 400
/
300
/   \
175   350
\
250
```
1. (3 points): 400 becomes the root

2. (3 points): 350 becomes the right subtree of 300

10. (10 points) 160 has just been inserted into the following AVL tree, causing it to violate the AVL condition:
```                          85
h=4
/    \
50     200
h=1     h=3
/       /   \
25     150   300
h=0     h=2   h=0
/   \
100  175
h=0  h=1
/
160
h=0
```
• Identify the bottom-most node that violates the AVL condition and explain why that node violates the AVL condition.

In the above tree I have labeled each node with its height. Since 200 is the first node whose subtree heights differ by more than 1, it is the first node to violate the AVL condition.

• Use the proper rotation(s) to rebalance the above tree so that it becomes a legitimate AVL tree.

We need to use a left-right double rotation since we have a left-right zig-zag. We will first do a left rotation about the grandchild of 200, which is 175, and then do a right rotation about 175:

```             85                        85                        85
/    \                    /    \                    /    \
50     200                 50   200                  50    175
/       /   \    left       /    /   \  right         /     /   \
25     150   300  rotation  25  175  300 rotation     25   150   200
/   \       ----->        /        ------>          /   \    \
100  175                  150                       100   160 300
/                   /   \
160                 100   160
```
1. _________ (3 points): identifies 200 as the node that violates the AVL condition

2. _________ (2 points): somewhere the answer must say that the height of 200's two children differs by 2 (or alternatively, more than 1).

3. __________ (2 points): 175 becomes the right child of 85

4. __________ (1 points): 200 becomes the right child of 175

5. __________ (1 points): 150 becomes the left child of 175

6. __________ (1 points): 160 becomes the right child of 150

7. __________ Deduct 2 points if the double rotation is performed correctly, but the node that is rotated about does not correspond to the one that should be chosen based on the answer to part a.

11. (12 points) Suppose you are given the following heap:
```                      ----5----
/         \
10           8
/    \        /  \
15      11     13  15
/  \    /  \    /
20  17  16  21  15
```
1. Draw the array represented by this heap (i.e., draw the array representation).
```Index:         0  1   2  3   4   5   6   7   8   9  10  11  12
Value:         ?  5  10  8  15  11  13  15  20  17  16  21  15
```
1. 1 point for having entry 0 be blank or a ?
2. 3 points for the rest of the array being correct, award partial credit if some but not all of the entries are correct

2. Show the heap that results from inserting 4. Please draw the resulting heap as a tree.

4 points: eyeball the answer. If the final answer is incorrect but some of the intermediate steps are shown, see if any of the intermediate steps agree with mine below.

1. Award 1 point for inserting 4 into the proper part of the tree
2. Award up to 3 points for doing some type of bubbling upwards (if 4 is placed in the wrong part of the tree but it's bubbled up correctly, then award 3 points for the bubbling up portion).

4 will be inserted at the first available location, which is as a right child of 13. Since 4 is less than 13 it will then swap locations with 13. We then compare 4 with 8 and since 4 is less than 8, it swaps locations with 8. Finally we compare 4 with 5 and since 4 is less than 5, swap 4 up to the root and 5 down to be a right child of 4. This gives us the final heap:

```                      ----4----
/         \
10           5
/    \        / \
15      11     8  15
/  \    /  \   / \
20  17  16  21 15 13
```
3. Show the heap that results from performing a deleteMin on the original heap. Please draw the resulting heap as a tree.

4 points: Partial credit:

1. (2 points) __________: 15 is promoted to the root but not percolated down

2. (2 points) __________: Some value other than 15 is promoted to the root and correctly percolated down

First we remove 5 from the tree, since it is the root and hence the minimum element in the heap. We then promote the bottommost, rightmost element, which is 15, to the root:

```                      ----15---
/         \
10           8
/    \        /  \
15      11     13  15
/  \    /  \
20  17  16  21
```
Next we compare 15 with its two children, 10 and 8, and promote the smaller of these, which is 8:
```                      ----8----
/         \
10          15
/    \       /  \
15      11    13  15
/  \    /  \
20  17  16  21
```
Again we compare the two new children of 15, 13 and 15, and select 13, which is the smaller. Since 15 is greater than 13, we promote 13, thus obtaining our final heap:
```                      ----8----
/         \
10          13
/    \       /  \
15      11    15  15
/  \    /  \
20  17  16  21
```

12. (14 points) Assume that you have a binary tree node that has been declared as follows:
```typedef struct node {
int salary;     // an employee's salary
char *name;     // an employee's name
struct node *leftChild;
struct node *rightChild;
} TreeNode;
```
Further assume that you have a binary search tree that is sorted based on an employee's salary. Write a function named printRange that traverses a binary tree and prints in sorted order all employees with a salary greater than or equal to a specified value. For example, given the following employee data:
```smiley 33000
mickey 20000
daffy 17000
tom 3000
dick 26000
mary 38000
susan 30000
joe 45000
```
and a request to print all employees with a salary greater than 25000, your function would print:
```dick      :   26000
susan     :   30000
smiley    :   33000
mary      :   38000
joe       :   45000
```
Your program should specifically meet the following specifications:

1. (1 point) it takes as parameters a pointer to root node of a binary tree and an integer representing the threshold salary.
2. (1 point) it returns nothing
3. it uses recursion to traverse the tree and print the employees whose salary is greater than or equal to the threshold salary.

1. (2 points) base case: it correctly stops the recursion when a null child is encountered. The only correct way to do this is to check whether or not the passed in pointer to the tree is null. If you check to see whether or not you are a leaf by checking your left and right children, then your code will seg fault if the initial tree is empty.
2. (2 points) it correctly determines whether or not the root node of the current subtree should be printed (it should be printed if the threshold is greater than or equal to the root node's salary)
3. (2 points) it correctly determines whether to recurse to the left subtree (it should recurse to the left subtree if the threshold is less than the root node's salary). Note that it is useless to visit the left subtree if the threshold is greater than or equal to the root node's salary, because none of the nodes in the left subtree will exceed the threshold value).
4. (2 points) it correctly determines whether to recurse to the right subtree (it should always recurse to the right subtree)

4. (2 points--0.5 point for each of the following items other than the colon) it prints employee names in a left-justified field that is 10 characters wide, followed by a colon (:), followed by a space, and then the salary in a right-justified field that is 7 characters wide.
5. (2 points): the answer is elegant and well-organied
```void printRange(TreeNode *root, int from) {
if (root == NULL)
return;
/* if from is less than the salary at the current node, then we need
to print at least some of the children in the left subtree */
if (from < root->salary)
printRange(root->leftChild, from);
/* we only want to print the current employee if from is less than
or equal to the employee's salary */
if (from <= root->salary)
printf("%-10s: %7.0f\n", root->name, root->salary);
/* we will always need to examine the entire right subtree. If from
is less than the current employee's salary, we will end up printing
all the employees in the right subtree. If from is greater than
the courrent employee's salary, then we may still end up printing
some of the employee's in the right subtree */
printRange(root->rightChild, from);
}
```

Alternative problem (worth 10/14 points): If you cannot think of a way to answer the above problem, then you can write a function named printTree that takes a pointer to the root node of a binary search tree and prints the employee's in descending order based on salary. printTree should return nothing. It should print employees using the same print specifications given above.

```void printInReverse(TreeNode *root) {
if (root == NULL)
return;
printInReverse(root->rightChild);
printf("%-10s: %7.0f\n", root->name, root->salary);
printInReverse(root->leftChild);
}
```