第二章 思考题

2-1(在归并排序中对最小数组采用插入排序) 虽然归并排序的最坏情况运行时间为θ(nlgn),而插入排序的最坏情况运行时间为θ( n2 ),但是插入排序中的常量因子可能使得它在n较小时,在许多机器上实际运行得更快。因此,在归并排序中当子问题变得足够小时,采用插入排序来使递归的叶变粗是有意义的。考虑对归并排序的一种修改,其中使用插入排序来排序长度为k的n/k个子表,然后使用标准的合并机制来合并这些子表,这里k是一个待定的值。
a) 证明:插入排序最坏情况可以在θ(nk)时间内排序每个长度为k的n/k个子表
b) 表明在最坏情况下如何在θ(nlg(n/k))时间内合并这些子表
c) 假定修改后的算法的最坏情况运行时间为θ(nk+nlg(n/k)),要使修改后的算法与标准的归并排序具有相同的运行时间,作为n的一个函数,借助θ记号,k的最大值是什么?
d) 在实践中,我们应该如何选择k?

a)
每张子表的排序时间为(1+n/k)*k/2=k/2+n/2
k张表为 k2/2+nk/2 ,故复杂度为θ(nk)
b)
将内容两两合并,第一次合并是复杂度是θ(n),一共比较了lg(n/k)次,故最坏情况下复杂度是nlg(n/k)
c)
nk+nlg(n/k)=nlgn解方程即可
d)
很多因素影响k,比如,操作系统中的分页机制,受内存来影响k。

2-2 (冒泡排序的正确性) 冒泡排序是一种流行但低效的排序方法,它的作用是反复交换相邻的未按次序排列的元素
BUBBLESORT(A)
for i=1 to A.length-1
    for j=A.length downto i+1
        if A[j]<A[j-1}
            exchange A[j]with A[j-1]
a) 假设A’表示BUBBLESORT(A)的输出。为了证明BUBBLESORT正确,我们必须钟明它将终止并且有:A’[1]<=A’[2]<=……<=A’[n],其中n=A.length。为了证明BUBBLESORT确实完成了排序,我们还需要证明什么?下面两部分将证明不等式
b) 为第2~4行的for循环精确地说明一个循环不变式,并证明该循环不变式成立。你的证明应该使用本章中给出的循环不变式证明的结构
c) 使用b部分的循环不变式的终止条件,为第1~4行的for循环说明一个循环不变式,该不变式将使你能证明不等式2.3。你的证明应该使用本章中给出的循环不变式证明的结构。
d) 冒泡排序的最坏情况运行时间是多少?与插入排序的运行时间相比,其性能如何?

b)
循环不变式证明如下:
初始化:i=1,j=n,确保A[n-1]<A[n]
保持:将A[j-1]和A[j]比较,使得A[j-1]<A[j]
终止:当j=i+1时循环终止,因为A[i]是已经排好的顺序,此时有A[i+1]是已经排好的顺序。
综上所述,此算法正确。
c)
初始化:i=1时,内循环将找出A[1…n]中的最小值,并赋值给A[1]。A[1]仅有一个元素,故A[1]已有序。
保持:如果i=k时,A[1…k]已有序。
终止:当i=n-1时,有A’[1]<=A’[2]<=…<=A’[n-1],而A’[n-1]是A[n-1]与A[n]中较小者,故定有A’[n-1]<=A’[n],故1到n有序。
综上所述,此算法正确。
d)
最坏时间是(1+n)n/2,插入排序是n^2,复杂度相同,均为θ( n2 )

2-3 (霍纳Horner规则的正确性)给定系数 a0,a1,,an 和x的值,代码片段
y=0
for i=n downto 0
    y=ai+x*y
实现了用于求值多项式

P(x)=k=0nakxk=a0+x(a1+x(a2))

的霍纳规则。
a)借助θ记号,实现霍纳规则的以上代码片段的运行时间是多少?
b)编写伪代码来实现朴素的多项式求值算法,该算法从头开始计算多项式的每个项。该算法的运行时间是多少?与霍纳规则相比,其性能如何?
c)考虑一下循环不变式:在第2~3行for循环每次迭代的开始有
y=k=0n(i+1)ak+i+1xk
把没有项的和式解释为等于0。遵照本章中给出的循环不变式证明的结构,使用该循环不变式来证明终止时有 y=nk=0akxk
d)最后证明上面给出的代码片段将正确地由系数 a0,a1,an 刻画的多项式的值。

a)
进行了n次运算,运行时间是θ(n)
b)
朴素多项式伪代码:

y=0
for i=0 to n
    y=y+ai*x^i

运行时间是θ( xn
霍纳规则的性能更高。
c)
循环不变式证明如下:
初始化:i=0时, y=a0=a0x0
保持:i=k时, y(k)=ak+y(k+1)=n(i+1)k=0ak+i+1xk
终止:i=n时, y=nk=0akxk
综上所述,此算法正确。
d)
这段代码本质是一个递归。

2-4 (逆序时)假设A[1…n]是一个有n个不同数的数组。若i
a)列出数组(2,3,8,6,1)的5个逆序对。
b)由集合(1,2,…,n)中的元素构成的什么数组具有最多的逆序对?它有多少逆序对?
c)插入排序的运行时间与输入数组中逆序对的数量之间是什么关系?证明你的回答。
d)给出一个确定在n个元素的任何排序中逆序对数量的算法,最坏情况需要θ(nlgn)时间(提示:修改归并排序)

a)
(1,5)、(2,5)、(3,5)、(4,5)、(3,4)
b)
倒序的数组具有最多的逆序对
个数是:n*(n-1)/2个
c)
逆序数等于交换的次数
d)
由c)可知,逆序数等于交换的次数。这样的话此题变成了复杂度为θ(nlgn)的算法。算法如下:

1)采用了分治的思想,改写了原先写好的归并/合并排序。
2)在每次“合并”的时候,分别拿出右侧子序列中的元素,到左侧子序列中比较来得出部分逆序数。
3)把三个部分的逆序数加在一起。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值