Exercises 2.1-all. 略。(除了提到了 linear-search, 没有值得记的东西)
Exercises 2.2-2.
selection-sort 运行时间对于所有情况都是 Θ(n^2)。其比较次数:(1+2+3+...+n-1) = n(n-1)/2 = Θ(n^2)。
Exercises 2.2-3.
linear-search 平均的比较次数为 (n+1)/2,Worst-case 比较次数为 n,所有情况运行时间都是 Θ(n)。平均比较次数的证明可以用数学期望:(1+2+3+...+n)/n = (n+1)/2
Exercises 2.3-2.
解决了无穷大在编程中不好表达的问题。
Exercises 2.3-5.
binary-search 对于排好序的数组,二分查找是一种树的结构,高度为 Θ(lgn)。CODE
Exercises 2.3-6.
参考官方 Solutions,Instructor's Manual, Second Edition
*Exercises 2.3-7.
我感觉这是第二章练习里最有意义的一道题目。已知三种解法:(1. 2. 参考)CODE
1. 先 Sort,然后从左右两边开始向中间夹,这种方法的证明好说,
但是算法基础是什么?(反证法即可证明算法正确性),其复杂度Θ(n*lgn+n),最优解。2. 先 Sort,然后遍历数组,用 binary-search 在右部分查找 x-a[i]。Worst-case 复杂度 Θ(n*lgn+lg(n!))。(lg(n!) = lgn+lg(n-1)+...+lg(2)+lg(1), Θ(lg(n!) = Θ(n*lgn)), P58, 3.19)
3. 参考 Instructor's Manual, Second Edition。其复杂度
Θ(2n*lgn+4n)Θ(n*lgn+4n)。
Problems 2-1.
a). 第一步的 Insertion-Sort 处理 n/k 个子集,每个子集含有k个元素。故 Θ(k^2*n/k) = Θ(nk)。
b). 回想 Merge-Sort 的复杂度计算:递归树有 lgn+1 层,进行 lgn 次同一层的Merge;虽然每一层有许多小的Merge组成,但总的复杂度是 Θ(n),故整个递归树的Merge复杂度是 Θ(n*lgn);另外考虑有n个子节点,处理所有子节点复杂度是 Θ(n) (参考P36注释9);因此,Merge-Sort 复杂度是 Θ(n*lgn+n)。同样,在这里递归树有lg(n/k)+1 层,Merge 的复杂度是 Θ(n*lg(n/k))。
c). 结合a)、b) 很容易得到总的复杂度是 Θ(nk+n*lg(n/k))。考虑k由1到n的过程,复杂度由 Θ(n+n*lgn) 到 Θ(n^2)。这里需要用到下一章增长率的知识,要找到最大的k,应该看到 nk+n*lg(n/k) 的 nk 部分最多由 n 到 n*lgn,此时 n*lg(n/k) 由 n*lgn 到 n*(lgn-lglgn),故 k=lgn。此时复杂度是 Θ(2n*lgn-n*lglgn)。
d). 从实践角度来讲,应该使k取使得 Insertion-Sort 比 Merge-Sort 快的最大值。直观地讲就是说,在谁有优势的时候用谁。
Problems 2-2.
bubblesort 冒泡排序。
a). 这个问题帮助提高思维的严谨性。除了A' 非递减,还需要证明其是A 的一个排列。
d). 不难计算冒泡排序执行 (n-1+...+2+1) = n(n-1)/2 次比较,复杂度 Θ(n^2)。虽然与 Insertion-Sort 一样,但平均情况下 Insertion-Sort 的比较次数少一半,不过复杂度是一样。
Problems 2-3.
Problems 2-4.
Inversions 逆序数。
b). 最坏情况下,随便取出两个数都是逆序数,因此最多有 n(n-1)/2 个。
c). 正如 Getting Started 杂碎里面提到的,对于 Insertion-Sort ,逆序数的个数就是其比较交换的次数。
d). 这个问题是我认为第二章第二有意义的题目。解法参考Instructor's Manual, Second Edition。
Chapter notes.