Subject: HW 3 Comments
From: Arefin Huq <[email-masked]>
To: Chee Yap <[email-masked]>
Date: Mon, 24 Mar 2008 11:20:44 -0400

Btw when I say "common mistake" or "some students" I mean at least  
two students (but usually more).

Problem 1
-------------
Common mistake: Some students provided a recursive solution, which  
works correctly and is the same complexity (and is indeed the only  
choice in some programming languages) but I deducted a point because  
I felt this is not the appropriate conceptual paradigm for working  
with linked lists and arrays.  If you disagree I'll be glad to return  
the points.

Common mistake: Some students treated a node u as an integer, e.g.  
"if u.key = key return u else u = u + 1".  I directed these students  
to see the solution and ask for clarification because I believe this  
is a basic error in understanding.

Problem 1.a and a' - insert
----------------------------------
Common mistake: A lot of students failed to check for duplicate keys  
and simply inserted the new item into the list.

Problem 1.a - delete
--------------------------
(Sorry I missed this before.)
The solution says that delete() can be done in O(1) time.  I don't  
agree because the list as described in the solution is singly-linked  
so there is no way to fix the pointer from the previous node without  
traversing the list.  Some students provided for a doubly-linked list  
in which case it can be done in O(1) time.

Problem 1.b - delete
--------------------------
There is some ambiguity about delete, as seen in students'  
solutions.  An ADT can support delete(key) or delete(node).  In the  
first case it is assumed that there are no duplicate keys, in the  
second case the ADT may or may not support duplicate keys.  The first  
case necessitates a lookup and the second does not.

For this problem delete(key) is O(n) and delete(node) is O(n) for a  
singly-linked list and O(1) for a doubly-linked list.  Instances of  
all three of these cases occurred in students' solutions.

Problem 1.a' and b'
-------------------------
Common mistake: Some students used the key K as the array index; in  
other words incorrectly assumed that K was an integer and indexed  
directly into a (potentially enormous and sparse) array.  Obviously  
in this case the complexity analysis in terms of n breaks down as well.

Alternative (and arguably better) solution: Some students kept the  
array sorted and used binary search, which keeps insert and delete at  
O(n) but improves lookup to O(lg n).

Problem 2
-------------
Most students had no problem with this.  I did not penalize for  
omitting update().  Some students were confused about what update() is.

Problem 4
-------------
Half the students got this and half were confused.
Common mistake: some students only provided an algorithm for turning  
a binary tree into a BST, which does not prove uniqueness
Common mistake: some students only gave general arguments without  
making use of any kind of induction (either structural or on the  
number of nodes)

Problem 5
-------------
Most students had no problem with this, except...

Ambiguity: there was confusion about what split means: when you split  
at a key K you rotate K to the root and now you have two subtrees TL  
and TR.  Some students took TL and TR to be T and T' (in other words  
K is now missing from both trees) whereas other students retained K  
as the root of one of the trees.  I do not know which is meant by the  
definition so I did not deduct points in either case as long as the  
rotations were done correctly, however you may want to clarify this  
to the students.

Problems 6 and 7
----------------------
[not yet graded]

Problem 8
-------------
Almost everyone got this.  Two students got incorrect answers because  
they used the standard Fibonacci sequence instead of the exact  
recurrence given.

Problems 10 and 11
-------------------------
People pretty much got these.