1. (12 points): 2 points each.
``` O(1)			    O(log n)	            O(n)
O(n log n)                 O(n2)	    AVL tree
Splay tree	            Binary search tree      Hash table
Open addressing	    Separate chaining       Linear probing
Hash function              Hash Table Size	    Rotation
Collision		    Hash function           Even number
2n-1            Prime number            2n
```
1. O(1): The average case time to find an item in a hash table is

2. O(n): The worst case time to find an item in a binary search tree

3. Rotation: The fundamental operation used to re-balance an AVL tree

4. Prime number: A good tablesize to choose for a hash table

5. AVL tree: A balanced tree scheme that guarantees that all insertions and finds will require O(log n) time

6. Separate chaining: A hashing scheme that uses lists to handle collisions

2. Multiply an integer, n, by 2 and assign the result to n. Your answer must use a bit expression, not multiplication.
n = n << 1;

3. Show the hash table that results if the integers 22, 28, 17, 21, 30 are inserted into the following hash table using:

• Linear probing, and
• the hash function h(k) = k % 7
```           -----------------------
0    |         28          |
|                     |
-----------------------
1	   |         22          |
|                     |
-----------------------
2    |         21          |
|                     |
-----------------------
3	   |         17          |
|                     |
-----------------------
4	   |         30          |
|                     |
-----------------------
5	   |                     |
|                     |
-----------------------
6	   |                     |
|                     |
-----------------------
```

4. Show the hash table that results if the integers 22, 28, 17, 21, 32 are inserted into the following hash table using:

• separate chaining, and
• the hash function h(k) = k % 5
You should append integers to the end of your lists.
```           -----------------------
0    |                     |
|                     |
-----------------------
1	   |                     |--> 21
|                     |
-----------------------
2    |                     |--> 22, 17, 32
|                     |
-----------------------
3	   |                     |--> 28
|                     |
-----------------------
4	   |                     |
|                     |
-----------------------
```

5. Show the binary search tree that results if 150 is deleted from the tree below:
```                           ---100---
/         \
50        -150-
/         /     \
25       125    -300-
/	    \
175	    400
\
250
/   \
200   275
```
To delete 150 we must find the smallest child in its right subtree, which is 175. 175 will get promoted to 150's spot but first we must delete 175 from the tree. When we delete 175 its right child gets promoted to 175's original spot as a descendent of 300. The final tree becomes:
```                           ---100---
/         \
50        -175-
/         /     \
25       125    -300-
/	    \
250	    400
/   \
200   275
```

6. Show the result of doing a single right rotation about the node 175. 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
/   \
200   275

```
The right rotation will cause 300 to become a right child of 175. In so doing the right subtree rooted at 250 will become an orphan because 300 is taking its place as 175's right child. Therefore 300 adopts 250 as its left child while keeping 400 as its right child. Note that it is ok for 300 to adopt 250 as its left subtree because all of the values in 250's tree are less than 300. The final tree becomes:
```                      175
\
300
/   \
250   400
/   \
200   275
```
7. Behold the following tree that violates the AVL condition:
```                          20
/    \
10     40
/    \
8     16
/
12
```
• Identify the bottom-most node that violates the AVL condition and explain why that node violates the AVL condition.

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

```                          20 h = 3
/    \
h = 2  10     40 h = 0
/    \
h = 0 8     16 h = 1
/
12 h = 0
```
• In order to rebalance the tree do we have to use the zig-zig case or the zig-zag case? Justify your answer.

We must use the zig-zag case. If we follow the route of the path followed for the insertion of 12, we see that we first went left, to 10, and then right, to 16. This left-right traversal is a zig-zag.

• 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 20, which is 16, and then do a right rotation about 16:

```                          20			         16
/  \				/  \
left rotation      16  40    right rotation       10  20
------------>     /	  -------------->     /  \   \
10			     8   12  40
/  \
8   12
```
The left rotation makes 10 be a left child of 16. 12 becomes orphaned in this process and since 10's right child is now freed up, 10 adopts 12 as its right child. The right rotation makes 20 be a right child of 16. This rotation is fairly simple since no orphans are created in the process and therefore no adoptions are required.

8. (12 points) Suppose you are given the following heap in array format:
```       14 19 16 26 21 19 68 65 31 32 44 23
```
1. Draw the heap represented by this array (i.e., draw the tree representation).

```                          ----- 14 -----
/              \
19                16
/    \             /  \
26        21        19    68
/  \      /  \      /
65  31    32  44    23
```
2. Show the heap that results from inserting 15. If you want partial credit then show your intermediate steps. Please draw the resulting heap as a tree.

Step 1: Insert 15 at the first available location:

```                          ----- 14 -----
/              \
19                16
/    \             /  \
26        21        19    68
/  \      /  \      /  \
65  31    32  44    23  15
```
Step 2: Bubble up 15 until it is greater than or equal to its parent. Since 15 is less than 19, we exchange 15 and 19:
```                          ----- 14 -----
/              \
19                16
/    \             /  \
26        21        15    68
/  \      /  \      /  \
65  31    32  44    23  19
```
Step 3: 15 is less than 16 so we exchange 15 and 16:
```                          ----- 14 -----
/              \
19                15
/    \             /  \
26        21        16    68
/  \      /  \      /  \
65  31    32  44    23  19
```
We are now finished because 15 is greater than 14. I could have shown the intermediate steps as holes, and only inserted 15 at the end, but I presented the solution like this to make it easier to follow.

3. Show the heap that results from performing a deleteMin on the original heap. If you want partial credit then show your intermediate steps. Please draw the resulting heap as a tree.

Here is the original tree:

```                          ----- 14 -----
/              \
19                16
/    \             /  \
26        21        19    68
/  \      /  \      /
65  31    32  44    23
```
A deleteMin involves the following steps:

Step 1: Remove the root, 14, and set it aside. Promote the bottom-most, right-most node in the tree, 23, to be the new root:

```                          ----- 23 -----
/              \
19                16
/    \             /  \
26        21        19    68
/  \      /  \
65  31    32  44
```
Step 2: Push down 23 to re-establish the heap property. We first compare 23's two children 19 and 16. Since 16 is the smaller of the two children, we compare 16 with 23. Since 16 is less than 23, we exchange 16 and 23:
```                          ----- 16 -----
/              \
19                23
/    \             /  \
26        21        19    68
/  \      /  \
65  31    32  44
```
Step 3: We compare 23's two new children, 19 and 68. 19 is less than 68 so we compare 19 with 23. Since 19 is less than 23, we exchange them:
```                          ----- 16 -----
/              \
19                19
/    \             /  \
26        21        23    68
/  \      /  \
65  31    32  44
```
23 is now a leaf so we are done.

9. (25 points) A binary expression tree is one in which the interior nodes are operators, such as + or -, and the leaves are numbers. For example:
```                     +
/     \
-       +
/   \    / \
-     4  8  10
/ \
16  5
```
This expression tree represents the arithmetic expression:
```     ((16-5) - 4) + (8+10)
```
which evaluates to 25. An expression tree can be evaluated by evaluating the left subtree, then the right subtree, and finally performing the indicated operation on the values returned by evaluating the left and right subtrees. A leaf evaluates to its number. For example, in the above expression tree, the + node with the leaves 8 and 10 evaluates to 18 since its left subtree evaluates to 8 and its right subtree evaluates to 10. Similarly the root + node evaluates to 25 because its left subtree evaluates to 7 and its right subtree to 18.

Your task is to write a function named evaluate that takes a binary tree node as a parameter and returns the integer value of its subtree. If the node is a leaf, the function will return the number associated with the leaf. Otherwise the function will evaluate the left and right subtrees, perform the operation indicated by the node on the results returned by the left and right subtrees, and return this value. A binary tree node has the following declaration:

```       typedef struct bnode {
int type;   // 0 for a leaf, 1 for an operator node
union {
char operator;  // can be either '-' or '+'
int number;
};
struct bnode *left;
struct bnode *right;
} BNode;
```
If the type field indicates that the node is a leaf, then the number field in the union will be set. If the type field indicates that the node is an operator node, then the operator field in the union will be set.
```#define LEAF 0

int evaluate(BNode *node) {
int left_value;
int right_value;
if (node->type == LEAF)
return node->number;
else {
// node is operator node. evaluate left and right subtrees, then
// combine the result
left_value = evaluate(node->left);
right_value = evaluate(node->right);
if (node->operator == '-')
return left_value - right_value;
else
return left_value + right_value;
}
}
```