《算法导论》笔记 第8章 总结与思考
【思考】
8-1 比较排序的平均情况下界
8-2 以线性时间原地置换排序
有一个由n个数据记录组成的数组要排序,且每个记录的关键字为0或1。
1) 算法的运行时间为O(n)
2) 算法是稳定的。
3) 算法是原地进行排序的。
a) 给出一个满足1、2的算法。
计数排序。
b) 给出一个满足1、3的算法。
采用类似快速排序中的PARTITION的方法,用两个指针分别从前往后、从后往前扫描,若(i>=j)则推出循环,否则将前面的第一个1与后面的最后一个0交换。
c) 给出一个满足2、3的算法。
所有稳定的原地排序算法皆可。
d) 在a、b、c中给出的算法能否用来在O(bn)时间内,对有b位关键字的n个记录进行基数排序?如果行,说明如何可做;如果不行,说明原因。
基数排序要求排序方法是稳定的且是时间为O(n),因此a)可行。
e) 假设n个记录中的每一个关键字都界于1到k之间。说明如何修改计数排序,使得可以在O(n+k)时间内对n个记录原地排序。除输入数组外,可以另用O(k)的存储空间。你给出的算法是稳定的吗?
void unStableCountingSort(int A[],int n,int k) { int C[MAXK]; int cnt=0; for (int i=0;i<=k;i++) { C[i] = 0; } for (int j=1;j<=n;j++) { C[A[j]]++; } for (int i=0;i<=k;i++) { while (C[i]>0) { A[++cnt]=i; C[i]--; } } }不稳定。
8-2 排序不同长度的数据项
a) 给定一个整数数组,其中不同的整数中包含的数字个数可能不同,但该数组中,所有整数中的总的数字数为n。说明如何在O(n)的时间内对该数组进行排序。
设字数为i的数字个数位mi。如果有m个元素,则m<=n。按字数进行基数排序复杂度Θ(n+m)即Θ(n),对字数相同的数字进行计数排序复杂度Θ(i*mi)。
则
b)给定一个字符串数组,其中不同的串包含的字符数可能不同,但所有串中总的字符个数为n。说明如何在O(n)时间内对该数组进行排序。
8-3 水壶
假设给定了n个红色的水壶和n个蓝色的水壶,它们的形状和尺寸都不相同。所有红色水壶中所盛水的量都不一样,蓝色水壶也是一样。
此外,对于每个红色的水壶,都有一个对应的蓝色水壶,两者所盛的水量是一样的。反之亦然。
你的任务是将所盛水量一样的红色水壶和蓝色水壶找出来。
为了达到这一目的,可以执行如下操作:挑选出一对水壶,其中一个是红色的,另一个是蓝色的:将红色水壶中倒满水;再将水倒入到蓝色的水壶中。
通过这个操作,可以判断出来这两只水壶的容量哪一个大,或者是一样大。
假设这样的比较需要一个时间单位。你的目标是找出一个算法,它通过执行最少次数的比较,来确定分组和配对问题。
记住不能直接比较两个红色的或两个蓝色的水壶。
a)给出一个确定型的算法,它利用Θ(n^2)次比较来完成水壶的配对。
将每个红水壶分别与n个蓝水壶进行比较。显然共比较了Θ(n^2)次。
b)证明:对于一个可以解决本问题的算法,必须执行的比较次数的下界为Ω(nlgn)。
采用决策树分析,配对方法共有n!种,每次比较有3个分支,若树的高度为h则3^h<=n!。
由斯特林公式(摘自苟神博客)
得h =Ω(nlgn)
c)给出一个随机化的算法,其期望的比较次数为O(nlgn),并证明这个界是正确的。对你的算法来说,最坏情况下的比较次数是什么?
选中一个红壶,将其与蓝壶进行比较,将蓝壶分为两部分,比它小的放在左边,比它大的放在右边。找到与红壶配对的蓝壶,将其与红壶比较,同理将红壶分为两部分。
递归处理两部分,最终以O(nlgn)的比较次数将红壶与蓝壶排好序,此时相同位置的红壶蓝壶是配对的。
8-5 平均排序
假设我们不是要排序一个数组,而只是要求数组中的元素一般情况下都是层递增序的。
更准确地说,称一个包含n个元素的数组A为k排序的(k-sorted),如果对所有i=1,2, ..., n-k,有下式成立:
a) 给出一个数组是1排序的是什么意思?
对这个数组进行排序。
b) 给出数字1,2, ..., 10的一个排列,它是2排序的,但不是完全排序的。
1 6 2 7 3 8 4 9 5 10
c) 证明:一个n元素的数组是k排序的,当且仅当对所有i=1,2, .... n-k 有 A[i] ≤ A[i+k]。
d) 给出一个算法,它能在O(nlg(n/k))时间内,对一个n元素的数组进行k排序。
由 c) 的结论可知,数组k排序即
A[1]<=A[1+k]<=A[1+2*k]<=A[1+3*k]....
A[2]<=A[2+k]<=A[2+2*k]<=A[2+3*k]....
将数据分为k个组,对每个组分别进行排序,每次排序的复杂度是O(n/klog(n/k))。
总复杂度O(nlog(n/k))。
e) 说明一个长度为n的k排序的数组可以在O(nlgk)内排序。
用最小堆做k路归并,复杂度为O(nlgk)。
f) 说明当k是一个常量时,需要Θ(nlgn)时间来k排序一个n元素的数组。(提示:可以利用前一部分的结果及比较排序的下界)。
用决策树得到k排序的下界。
一个n个元素的数组最后生成的k排序的数目
决策树的高度h满足
即复杂度为Ω(nlgn)
基于比较排序的下界为O(nlgn)
因此当k是一个常量时,需要Θ(nlgn)时间来k排序一个n元素的数组。
8-6 合并已排序列表的下界