(1). False. f(n) = Theta(g(n)) implies log(f(n)) = Theta(log(g(n))), but
not the other way around.  Consider f(n) = 2^{n} and g(n) = 2^{n/2}.
Clearly, log(f(n)) = n = Theta(n/2) = Theta(log(g(n))), but f(n) is
not Theta(g(n)).

(2-a). Use the recursion tree approach.  The first level contributes
n^2, the second level (n/3)^2 + (2n/3)^2 = 5n^2/9.  The third level
contributes (n/9)^2 + (2n/9)^2 + (2n/9)^2 + (4n/9)^2 = 25n^2/81.
Thus, the contributions are decreasing geomterically.  This implies
that T(n) is at most n^2(1 + 5/9 + (5/9)^2 + ...), which is at most
9n^2/4.  Clearly, T(n) is at least n^2.  Therefore, T(n) = Theta(n^2).

(2-b). Use the master theorem.  f(n) = nlgn.  n^{log_b a} = n^{lg 3}.
Since lg 3 > 1.5 and nlgn = O(n^{1.5}) (which can be proved by using
the ``limit theorem'' and applying L'Hopital's rule), we invoke case 1
and obtain T(n) = Theta(n^{lg 3}).

(3-a). We find the element of rank 2^{k}/2 which takes at most 10n
comparisons.  Then, we partition the set into the two halves around
this element, which takes 2^k comparisons.  So, in all, 11*2^{k}
comparisons.

(3-b). Apply the same argument as above to the two halves.  We get
another 2*11*2^{k-1} comparisons thus yielding a total of 22*2^{k}
comparisons.

(3-c). Generalize the above argument.

(3-d). Yes, it is asymptotically optimal.  If we set n=2^k, (11k)2^k =
11n*logn = Theta(n lg n).  Since any comparison-based algorithms needs
Omega(n lg n) comparisons n the worst-case, this is asymptotically
optimal.

(4) If we insert the numbers 1, 2, ..., n in sequence into a binary
search tree, we obtain a line.  This can be easily proved by
induction.  In order to obtain a complete binary tree, we consider the
sequence that is defined recursively as follows.  Let S_k denote the
sequence of insert requests that yields the complete binary tree on
2^k - 1 nodes.  For a given sequence S = s_1, ..., s_j, let S + x
denote the sequence s_1 + x, s_2 + x, ... s_j + x.  We now define S_k
as:

S_k =   1 if k = 0
        2^{k-1}, S_{k-1}, S_{k-1} + 2^{k-1} if k > 0.
        
Note that according to S_k, we first insert the median element
of the 2^k - 1 elements, then recursively the smallest 2^{k-1}
- 1 elements and then recursively the largest 2^{k-1} - 1
elements.  One can prove using induction that that the above
sequence yields a complete binary tree.

(5). We store the following fields in each node: key, left, right,
color (red or black), parent, min, max, and min-gap.  The fields
min[x] and max[x] store the minumum and maximum values, respectively,
stored in the subtree rooted at x.  The field min-gap[x] stores the
min-gap among elements stored in the subtree rooted at x.  We now show
that these fields at x can be calculated from the children of x and
the other fields in x.  We might also want to store the two values
that yield the min-gap.

min[x] = min[left[x]], if left[x] exists; and key[x], otherwise.

max[x] = max[right[x]], if right[x] exists; and key[x], otherwise.

min-gap[x] = minimum of min-gap[left[x]], min-gap[right[x]], key[x] -
max[left[x]] (if left[x] exists), and min[right[x]] - key[x] (if
right[x] exists).  Also store the corresponding values that yield the
minimum.

Now, using the theorem about augmenting red-black trees, it follows
that insertion and deletion can be done in O(log n) time.  Finally,
the min-gap for the whole set can be obtained by simply returning the
min-gap values stored at the root.

