6.1 template bool Compare(GTNode* t1, GTNode* t2) { GTNode *c1, *c2; if (((t1 == NULL) && (t2 != NULL)) || ((t2 == NULL) && (t1 != NULL))) return false; if ((t1 == NULL) && (t2 == NULL)) return true; if (t1->value() != t2->value()) return false; c1 = t1->leftmostChild(); c2 = t2->leftmostChild(); while (!((c1 == NULL) && (c2 == NULL))) { if (!Compare(c1, c2)) return false; if (c1 != NULL) c1 = c1->rightSibling(); if (c2 != NULL) c2 = c2->rightSibling(); }} This algorithm has a worst case running time of Theta(n), where n is the total size of both trees. 6.8 The array will contain 4 4 4 4 -1 4 4 0 0 4 9 9 9 12 9 -1 where -1 indicates a root. 6.13 Base case: n = 0. The tree consists of one node, which is both the root and the only leaf. Since (K-1)0 + 1 = 1, the base case holds. Induction step: assume the result holds for full K-ary trees with n internal nodes, and let T be a full K-ary tree with n+1 internal nodes. Take any internal node of maximum depth. It has K children, all of which are leaves. Delete these leaves, getting a complete K-ary tree with n internal nodes. By the induction assumption, this tree has (K-1)n + 1 leaves. Therefore T has (K-1)n + 1 + (K-1) = (K-1)(n+1) + 1 leaves, and the result holds for n+1. 6.15 (a) Ignoring the root, every node has overhead fraction 4(K + 1) K + 1 ____________ = _____ 4 + 4(K + 1) K + 2 (b) 4K K _______ = _____ 4K + 16 K + 4 (c) From the previous exercise, there are about K-1 leaves for every internal node. For any internal node and any set of K-1 leaves, there are a total of 2K pointers and K data fields, so the overhead fraction is about 8K 1 ___ = _ 16K 2 Or, if you prefer to do it exactly, let n = number of internal nodes. Then the overhead fraction is n(4(K+1)) + ((K-1)n + 1)4 8Kn + 4 1 ______________________________ = _________ = _ (approx.) n(8 + 4(K+1)) + ((K-1)n + 1)12 16Kn + 12 2 (d) 2K K ______ = ______ 6K - 4 3K - 2 Or, if you prefer to do it exactly, let n = number of internal nodes. Then the overhead fraction is n(2K) 2Kn K _____________________ = ___________ = ______ (approx.) n(2K) + ((K-1)n + 1)4 (6K-4)n + 4 3K - 2 7.10 (a) Each call to qsort costs \Theta(i log i) on average. So the total average cost is sum_{i=1}^{n} \Theta(i log i) We can simplify this sum as follows: sum_{i=1}^{n} i log i < sum_{i=1}^{n} n log n = n^2 log n and sum_{i=1}^{n} i log i > sum_{i=n/2}^{n} n/2 log(n/2) = \Omega(n^2 log n) so sum_{i=1}^{n} \Theta(i log i) = \Theta(n^2 log n) (b) Each call to qsort costs \Theta(n log n). So the total cost is \Theta(n^2 log n) 7.14 (a) The worst case happens when all of the sublists are of size 1, except for one list of size n-k+1. When SORTk is called recursively on the large sublist, the worst case again occurs if one of the sublists has size n-2(k-1), and so on. If this happens on each call to SPLITk, we can use a recurrence to estimate the worst case run time: T(1) = 1 T(n) = n + T(n-k). Unwinding the recurrence, and assuming that n = (n/k)k exactly, T(n) = n + n-k + n-2k + n-3k + ... + 0 Therefore T(n) = n^2 -((n/k)(n/k + 1)/2)k = \Theta(n^2). (b) In the average case the sublists will be of nearly equal size. That is, the first time they will be of size n/k, the next time n/k^2, etc. That is, the depth of recursion will be log_k n. This time the recurrence is: T(1) = 1 T(n) = n + kT(n/k). Unwinding the recurrence, and assuming that n = k^d exactly for some d, T(n) = k^d + dn = n + nlog_k(n) = \Theta(nlog n).