《算法导论》笔记 第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 合并已排序列表的下界




posted on 2014-04-12 21:42  电子幼体  阅读(367)  评论(0编辑  收藏  举报

导航