导航

算法导论第三版第二章第三节习题答案

Posted on 2013-03-05 10:53  蝈蝈俊  阅读(3208)  评论(0编辑  收藏  举报

2.3-1 以图2-4为模型,说明合并排序在输入数组A={3,41,52,26,38,57,9,49}上的执行过程。

        3 9 26 38 41 49 52 57      
      3 26 41 52 & 9 38 49 57      
  3 41 & 26 52       38 57 & 9 49  
3 & 41   52 & 26   38 & 57   9 & 49

注:&为合并符号。

如果是 对数组 6,4,7,26,38,45,9使用插入排序呢?如下

 

        4 6 7 9 26 38 45        
      4 6 7 26 & 9 38 45        
  4 6 & 7 26       38 45 & 9    
6 & 4   7 & 26   38 & 45      

=========================================================================

2.3-2 改写MERGE过程,使之不使用哨兵元素,而是在一旦数组元素L或R中的所有元素都被复制回数组A后,就立即停止,再将令一个数组中余下的元素复制回数组A中。

go语言实现的代码: http://www.cnblogs.com/ghj1976/archive/2013/02/28/2937319.html

 

NewImage

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

NewImage

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

=========================================================================

2.2-3 利用数学归纳法证明:当n是2的整数次幂时,以下递归式的解是T(n)=nlgn。

NewImage

 

 

 

最简单和常见的数学归纳法证明方法是证明当n属于所有正整数时一个表达式成立,这种方法是由下面两步组成:
递推的基础:证明当n=1时表达式成立。
递推的依据:证明如果当n=m时成立,那么当n=m+1时同样成立。
这种方法的原理在于第一步证明起始值在表达式中是成立的,然后证明一个值到下一个值的证明过程是有效的。如果这两步都被证明了,那么任何一个值的证明都可以被包含在重复不断进行的过程中。

 

http://baike.baidu.com/view/284458.htm

证明:

1、当n=2时,T(n)=2lg(2)=2成立。

2、假设当n=2^k(k>1)时,等式成立,即T(2^k)=(2^k)lg(2^k)=k(2^k);

又因为已知:n=2^k(k>1)时,有T(2^k)=2T((2^k)/2)+2^k,

所以:T(2^(k+1))= 2T((2^(k+1))/2)+2^(k+1)= 2T(2^k)+2^(k+1)= 2(k*(2^k))+2^(k+1)= (k+1)*2^(k+1)

3、所以,当n=2^(k+1) (k>1)时,等式也成立。即递归式的解确实为T(n)=nlg(n)。

NewImage

 

 

 

 

 

 

 

 

 

 

 

============================================================================================

2.3-4:插入排序可以如下改写成一个递归过程:为排序A[1..n],先递归地排序A[1..n-1],然后再将A[n]插入到已排序的数组A[1..n-1]中去。对于插入排序的这一递归版本,为它的运行时间写一个递归式。

https://github.com/Airead/excise/blob/master/algorithms/excise/2.3-4.txt

伪代码:

NewImage

 

 

 

 

 

 

 

 

 

 

递归式的答案比较糊涂,网上有几个版本:

http://www.cnblogs.com/sinoxavier/archive/2012/11/23/2785077.html

n<=C时,T(n)=Θ(1),否则T(n)=(n-1)/n*T(n-1)+ Θ(n^2)

http://www.cnblogs.com/liao-xiao-chao/articles/2351925.html

T(n)     =     Θ(1)  n=1 or 2
    =  T(n-1)+ Θ(n)  n>2

http://www.cnblogs.com/timebug/archive/2010/03/13/1685319.html

NewImage

 

 

 

 

https://github.com/Airead/excise/blob/master/algorithms/excise/2.3-4.txt

T(n) = T(n-1) + cn = T(1) + (n-1)cn = 1 + cn(n-1)
T(n) = O(n^2)

 

============================================================================================

2.3-5 回顾查找问题(参见练习2.1-3),注意到,如果序列A已排好序,就可以将该序列的中点与v进行比较。根据比较的结果,原序列中有一半就可以不用再做进一步的考虑了。二分查找算法重复这个过程,每次都将序列剩余部分的规模减半。为二分查找写出迭代或递归的伪代码。证明:二分查找的最坏情况运行时间为Θ(lgn)。 

2.1-3的试题如下:考虑下面的查找问题:

输入:一列数A=<a1,a2,…,an >和一个值v
输出:下标i,使得v=A[i],或者当v不在A中出现时为NIL。
写出针对这个问题的现行查找的伪代码,它顺序地扫描整个序列以查找v。
利用循环不变式证明算法的正确性。确保所给出的循环不变式满足三个必要的性质。

NewImage

 

 

 

 

 

 

 

 

 

 

 

 

 

NewImage

 

 

 

 

 

 

 

 

 

 

 

 

二分查找最坏的情况是直到最后次二分也未找到相应的值,假设总量n等于2的k次方,即n=2^k,每二分一次k减1,当k=0时,之前一次为最后一次二分,即共执行了k次。而k=lg(n),所以,最坏情况的运行时间为Θ(lgn)。

============================================================================================

2.3-6 注意到2.1节中的过程INSERTION-SORT的第5~7行的while循环采用一种线性查找来(反向)扫描已排好序的子数组A[1..j-1]。我们可以使用二分查找(参见练习2.3-5)来把插入排序的最坏情况总运行时间改进到Θ(nlgn)吗?

在最坏情况下,二分查找的时间复杂度是 nlgn,但插入时数组移动的时间复杂度仍是 n2 。
故总体运行时间不能改善为 Θ(nlgn)。(但若排序中采用链表的数据结构,则可改善。)

插入排序的算法

NewImage

 

 

 

 

 

 

 

 

二分法查找,但是数据插入仍然用之前方法,时间复杂度仍然是n^2

NewImage

 

 

 

 

 

 

 

用链表的时间复杂度

NewImage

 

 

 

 

 

 

 

============================================================================================

*2.3-7 描述一个运行时间为Θ(nlgn)的算法,给定n个整数的集合S和另一个整数x,该算法能确定S中是否存在两个其和刚好为x的元素。

NewImage

 

 

 

 

 

 

 

算法思路1:
首先对S[1...n]进行非降序排序,然后设置两个指向标i=1,j=n,执行下面的操作:
S[i] + S[j] = X,  返回true
          < X,  i = i+1
    > X,  j = j-1
  如果 i>j 返回false

正确性说明:很显然,如果S[i] + S[j]< X,则如果存在一个a,使得S[a] + S[j] = x,
那么这个S[a]一定要大于s[j],换句话说a要大于i,
另外一种情况是存在一个a,使得S[i] + S[a] = x,那么这个S[a]一定要大于s[j],换句话说a要大于j,
下面我们说明第二种情况不存在,在执行到j前,因为偏移量总是1,所以必然会执行到a,
这个时候在i之前的所有数,与S[a]相加是要小于X的,根据上面的公式,会移动前半段,即变动i,
直到到达i,所以不存在,同理可以说明>X的情况,因此如果算法返回false的话,
算法可以验证那么对于任意的i,都不存在j使得其和等于X
时间复杂度分析:排序为Θ(nlgn),之后为Θ(n),算法的时间复杂度为Θ(nlgn)

思路2:

NewImage

 

 

 

 

 

 

 

思路3:
以算法导论上面的标准答案步骤是这样的:
1)将S中的元素排序。
2)构建另一个集合S‘={z:z=x-y , 其中y属于S}。
3)对S‘中的元素排序。
4)如果S中有元素出现多余一次,则移除多余的,只剩下一个。对于S’也移除重复的元素。
5)合并两个排好序集合S和S‘。
6)只要在合并好的集合中有同样的元素出现两次(它们必然在相邻的位置),则存在和为x的两个数。假定该元素为y,则另一个元素为x-y。
第1,3步所需时间为O(nlgn),2,4,5,6步所需时间为O(n)。所以总的时间为O(nlgn)。

 

 

 

 

 

============================================================================================

 

参考资料:

http://www.cnblogs.com/timebug/archive/2010/03/13/1685319.html

http://www.cnblogs.com/liao-xiao-chao/articles/2351925.html

http://qiemengdao.iteye.com/blog/1328678

http://www.cnblogs.com/sinoxavier/archive/2012/11/23/2785077.html

https://github.com/Airead/excise/blob/master/algorithms/algorithms.org