Paper Portion

  1. (10 points): BSTree insertion. You will need to use your judgment in grading this problem. If you cannot make any sense of their tree, then you will need to deduct 10 points. If it seems mostly correct, then it's roughly 1 point for each correctly positioned key.

  2. (10 points): BSTree deletion: You will need to use your judgment in grading this problem. Below are some guidelines on how to assign points. You should also make minor deductions if they have modified other parts of the tree that shouldn't be modified.

    1. (5 points): sarah replaces susan

    2. (5 points): rebecca promoted to be the right child of peter while continuing to have ralph as a left child

    3. peter should not get ralph as a left child. Deduct 3 points if this happens.

    If they try to delete from the right subtree instead, then they get 5 points of partial credits follows:

    1. (3 points): xavier replaces susan

    2. (2 points): xavier is deleted as yifan's left child.

  3. (10 points) Rotation: You will need to use your judgment in grading this problem. Below are some guidelines on how to assign points. You should also make minor deductions if they have modified other parts of the tree that shouldn't be modified.

    1. (3 points) 500 becomes the root of the entire tree

    2. (4 points) 300 becomes the left child of 500

    3. (3 points) 400 becomes the right child of 300

  4. (12 points): AVL trees: You will need to use your judgment in grading this problem. Below are some guidelines on how to assign points. You should also make minor deductions if they have modified other parts of the tree that shouldn't be modified.
    1. Identify the bottom-most node that violates the AVL condition and explain why that node violates the AVL condition.

      1. (2 points): identifies 100 as the node that violates the AVL condition

      2. (1 points): uses a height calculation to show that the height of 200 is 2 and the height of 40 is 0, and hence that the two children's height differs by 2. It is not enough for the answer to say that the height of 100's two children differs by 2.

    2. In order to rebalance the tree do we have to use the zig-zig case or the zig-zag case? Justify your answer.
      1. (2 points): Answer is zig-zag

      2. (1 points): Good, well-reasoned justification
    3. Use the proper rotation(s) to rebalance the above tree so that it becomes a legitimate AVL tree.

      1. (2 points): 100 becomes the left child of 150

      2. (2 points): 200 becomes the right child of 150

      3. (1 points): 125 becomes the right child of 100

      4. (1 points): 175 becomes the left child of 175

  5. (10 points)

  6. (15 points): You will need to use some judgement in deducting points on this problem because some students are going to do unexpected things, such as missing one or two stack frames, or using variable names like x/y rather than a/b. When unexpected things happen, use your judgement in deciding how many points to deduct.

  7. (12 points) 3 points each, all or nothing

  8. (12 points) 2 points for each subpart, all or nothing. The exceptions are:


Coding Problems

  1. Leaf Count

    1. -3: Too many calls to recursive_leaf_count. For example, the logic for the base case might call recursive_leaf_count and then rather than returning with a result if it is the base case, continuing onto the recursive case and again making calls to recursive_leaf_count.
    2. -3: Determining if a node is a leaf by checking if the left and right children are NULL rather than the sentinel node
    3. -4: Adding 1 to the leaf count for an internal (i.e., non-leaf) node
    4. -8: Only counting leaves in either the left or right subtree rather than counting leaves in both subtrees
    5. -6: Missing the base case where the node is a leaf and the function should return 1
    6. -15: missing or incorrect recursive case where the node is an internal node
    7. -1: using conditions that are guaranteed to be either true or false, and hence are a waste of the CPU's time. If your code has multiple such conditions, you will lose multiple points.
    8. -1 to -10: using hard to read or poorly organized code
    9. -1: Correctly checking to see if the node is a leaf node by checking if its left and right children are sentinel nodes, but putting this check after the recursive calls to leafcount and thus wasting time by making unnecessary recursive calls.

  2. String Reversal
    1. -3: The recursive function should not return a string. It should modify the original string passed in as a parameter. Returning a string is inefficient as it will turn what should be an O(n) algorithm into an O(n2) algorithm, where n is the length of the original string. The reason is that generally the base case will return a string of length 0 or length 1, and then you will return strings that increase in size by 2, hence either 0, 2, 4, 6, ... or 1, 3, 5, 7, ... length strings. There are n/2 recursive calls required to reverse the string, since each recursive call swaps two characters. Hence the number of characters required to construct the n/2 strings constructed by the recursive calls is:
      T(n) = 0 + 2 + 4 + 6 + ... + n-2 + n
                  
      If you pair up the numbers at the beginning and end of this sequence you get (0, n), (2, n-2), (4, n-4), etc. and the sum of each pair is n. There are n/4 such pairs (because there were n/2 recursive calls), so T(n) = n * (n/4) = n2/4. Hence the running time of your algorithm is O(nn2) if you return a string from each of your recursive functions.

    2. -3: Not using the recursive reversal algorithm given in the problem write-up of swapping the first and last characters, then the second and next to last characters, and so on. This is the most efficient way to do the reversal since it requires only n/2 recursive calls, where n is the original length of the string. You can also reverse the string by reversing the remaining n-1 characters and then appending the first character to the end of the string, but this is very inefficient because you will have to somehow erase the first character from the start of the string, which is an O(n) operation. Since there are n characters in the string, you will need to repeat this procedure n times, which leads to an O(n2) algorithm.

    3. -1 - -10: Improperly or inefficiently swapping the two characters.
    4. -1: using conditions that are guaranteed to be either true or false, and hence are a waste of the CPU's time. If your code has multiple such conditions, you will lose multiple points.

    5. -1/-2: checking conditions in the recursive helper function that should be checked only once in the top-level "wrapper" function. For example, checking if the original string is empty or only one character should be done once, in the top-level "wrapper" function, not every time in the recursive helper function.

    6. -3: not modifying the original string but instead trying to construct a new string.

    7. -10: not correctly swapping characters

    8. -1: The recursive helper and wrapper functions should be void functions. The "return" value is the original string passed in as a reference parameter.