算法导论第二章
思考题
2-1
证明:
已知插入排序的最坏情况运行时间为Θ ( n 2 ) Θ(n^{2}) Θ ( n 2 ) ,且我们使用插入排序来排序长度为k k k 的n / k n/k n / k 个子表。
长度为k k k 的一个子数组,用插入排序其最坏情况运行时间为Θ ( k 2 ) Θ(k^{2}) Θ ( k 2 ) ,且有n / k n/k n / k 个子表,得出Θ ( n k × k 2 ) Θ(\dfrac{n}{k} \times k^{2}) Θ ( k n × k 2 ) ,结果为Θ ( n k ) Θ(nk) Θ ( n k )
举个例子:当一个总长度为n n n 的输入( n > 1 ) (n > 1) ( n > 1 ) ,经过一次归并排序递归后,将n n n 一分为二,也就是n / 2 n / 2 n / 2 ,如果k k k 为代表的当前这次的长度n / 2 n / 2 n / 2 ,则我们可以得出层数:
l g ( n / k ) + 1 = = l o g 2 ( n / k ) + 1 = = l o g 2 ( n / n 2 ) + 1 = = l o g 2 ( 2 ) + 1 = = 2 lg(n/k)+1==log_{2}(n / k)+1==log_{2}(n / \dfrac{n}{2})+1==log_{2}(2)+1==2 l g ( n / k ) + 1 = = l o g 2 ( n / k ) + 1 = = l o g 2 ( n / 2 n ) + 1 = = l o g 2 ( 2 ) + 1 = = 2
得到层数为2。
同理,当我们再一次经过归并排序递归后,n / 2 n/2 n / 2 再次一分为2 2 2 ,也就是( n / 2 ) / 2 = = n / 4 (n/2)/2==n/4 ( n / 2 ) / 2 = = n / 4 ,k k k 为n / 4 n/4 n / 4 ,代入上面的式子,得出层数3。
我们可以得出,l g ( n / k ) + 1 lg(n/k)+1 l g ( n / k ) + 1 即为归并排序递归的层数,因为合并算法MERGE的最坏情况运行时间为Θ ( n ) Θ(n) Θ ( n ) ,得出n l g ( n / k ) + n nlg(n/k)+n n l g ( n / k ) + n ,去掉常量,得出Θ ( n l g ( n / k ) ) Θ(nlg(n/k)) Θ ( n l g ( n / k ) )
最大值是k = l g n k=lgn k = l g n ,如果我们替代,我们得到:
Θ ( n l g n + n l g n l g n ) = Θ ( n l g n ) Θ(nlgn+nlg\dfrac{n}{lgn})=Θ(nlgn) Θ ( n l g n + n l g l g n n ) = Θ ( n l g n )
如果k = f ( n ) > l g n k=f(n)>lgn k = f ( n ) > l g n ,复杂性将是Θ ( n f ( n ) ) Θ(nf(n)) Θ ( n f ( n ) ) ,它比合并排序的运行时间大
It’s constant factors, so we just figure out when insertion sort beats merge
sort, exactly as we did in exercise 1.2.2, and pick that number for k.
(这是常数因子,所以我们只找出插入排序比合并排序,完全像我们在练习 1.2.2 1.2.2 1 . 2 . 2 中所做的那样,并选择该数字K K K .)
2-2
BUBBLESORT ( A)
1 for i = 1 to A. length - 1
2 for j = A. length downto i + 1
3 if A[ j] < A[ j - 1 ]
4 exchange A[ j] with A[ j - 1 ]
We need to prove that A’ consists of the original elements in A, although in (possibly) different order.
(我们需要证明A’由A中的原始元素组成,尽管顺序可能不同。)
循环不变式( 2 (2 ( 2 ~4 ) 4) 4 ) :
(1)总是从最后一个元素开始递减,且后前一位元素进行判断交换
(2)每循环一次后,A [ j ] A[j] A [ j ] 是A [ j . . A . l e n g t h ] A[j..A.length] A [ j . . A . l e n g t h ] 中最小的元素
证明:
初始化:循环的第一次迭代i i i 为首元素,j j j 为尾元素,判断式为真,开始执行循环
保持:进行A [ j ] A[j] A [ j ] 和A [ j − 1 ] A[j - 1] A [ j − 1 ] 的判断,如果A [ j ] > A [ j − 1 ] A[j] > A[j - 1] A [ j ] > A [ j − 1 ] 则交换换元素中的数据,我们可以得知,A [ j ] A[j] A [ j ] 将会是A [ j ] 和 A [ j − 1 ] A[j]和A[j-1] A [ j ] 和 A [ j − 1 ] 中最小的一个,同理,A [ j ] A[j] A [ j ] 也会是A [ j . . A . l e n g t h ] A[j..A.length] A [ j . . A . l e n g t h ] 中最小的。
终止:因为每次循环后,A [ j ] A[j] A [ j ] 总是A [ j . . A . l e n g t h ] A[j..A.length] A [ j . . A . l e n g t h ] 中最小的,所以退出循环后,A [ i ] A[i] A [ i ] 将会是A [ i . . A . l e n g t h ] A[i..A.length] A [ i . . A . l e n g t h ] 中最小的数字
循环不变式( 1 (1 ( 1 ~4 ) 4) 4 ) :
(1)每次循一次后,A [ 1.. i ] 都 是 排 好 序 的 A[1..i]都是排好序的 A [ 1 . . i ] 都 是 排 好 序 的
证明:
初始化:循环的第一次迭代i i i 为首元素,且循环至i i i 大于A . l e n g t h − 1 A.length-1 A . l e n g t h − 1 ,第一次判断式为真,开始执行循环
保持:已经证明了每当执行完次( 2 (2 ( 2 ~4 ) 4) 4 ) 循环时,A [ j ] A[j] A [ j ] 是A [ j . . A . l e n g t h ] A[j..A.length] A [ j . . A . l e n g t h ] 中最小的元素,得到当前循环每迭代循环一次,其A [ 1.. i ] A[1..i] A [ 1 . . i ] 将总是排序好的
终止:当i i i 大于A . l e n g t h − 1 A.length-1 A . l e n g t h − 1 终止,A [ 1.. i ] A[1..i] A [ 1 . . i ] 将是排序好的,也相当于说A [ 1.. A . l e n g t h − 1 ] A[1..A.length-1] A [ 1 . . A . l e n g t h − 1 ] 是排序好的,最后一个元素不用排序,因为它一定是A中最大元素,也理应在最后一位
最坏情况运行时间为Θ ( n 2 ) Θ(n^{2}) Θ ( n 2 )
BUBBLESORT ( A)
1 for i = 1 to A. length - 1 c1 n
2 for j = A. length downto i + 1 c2 ①
3 if A[ j] < A[ j - 1 ] c3 ②
4 exchange A[ j] with A[ j - 1 ] c4 ②
① ∑ j = 2 n t j \sum ^{n}_{j=2}t_{j} ∑ j = 2 n t j
② ∑ j = 2 n ( t j − 1 ) \sum ^{n}_{j=2}\left( t_{j}-1\right) ∑ j = 2 n ( t j − 1 )
该算法的运行时间(执行每条语句的运行时间之和)是:
T ( n ) = C 1 n + C 2 ∑ j = 2 n t j + C 3 ∑ j = 2 n ( t j − 1 ) + C 4 ∑ j = 2 n ( t j − 1 ) T\left( n\right) =C_{1}n+C_{2}\sum ^{n}_{j=2}t_{j}+C_{3}\sum ^{n}_{j=2}\left( t_{j}-1\right)+C_{4}\sum ^{n}_{j=2}\left( t_{j}-1\right) T ( n ) = C 1 n + C 2 ∑ j = 2 n t j + C 3 ∑ j = 2 n ( t j − 1 ) + C 4 ∑ j = 2 n ( t j − 1 )
其中我们注意到:
∑ j = 1 n t j \sum ^{n}_{j=1}t_{j} ∑ j = 1 n t j = ( n ( n + 1 ) 2 − 1 ) \left( \dfrac {n\left( n+1\right) }{2}-1\right) ( 2 n ( n + 1 ) − 1 )
∑ j = 2 n ( t j − 1 ) \sum ^{n}_{j=2}\left( t_{j}-1\right) ∑ j = 2 n ( t j − 1 ) = n ( n − 1 ) 2 \dfrac {n\left( n-1\right)}{2} 2 n ( n − 1 )
最坏情况运行时间
T ( n ) = C 1 n + C 2 ( n ( n + 1 ) 2 − 1 ) + C 3 ( n ( n − 1 ) 2 ) + C 4 ( n ( n − 1 ) 2 ) T\left( n\right) =C_{1}n+C_{2}\left( \dfrac {n\left( n+1\right) }{2}-1\right)+C_{3}\left( \dfrac {n\left( n-1\right)}{2}\right)+C_{4}\left( \dfrac {n\left( n-1\right)}{2}\right) T ( n ) = C 1 n + C 2 ( 2 n ( n + 1 ) − 1 ) + C 3 ( 2 n ( n − 1 ) ) + C 4 ( 2 n ( n − 1 ) )
= ( C 2 2 + C 3 2 + C 4 2 ) n 2 + ( C 1 + C 2 2 − C 3 2 − C 4 2 ) n − C 2 =\left( \dfrac {C_{2}}{2}+\dfrac {C_{3}}{2}+\dfrac {C_{4}}{2}\right) n^{2}+\left(C_{1}+\dfrac {C_{2}}{2}-\dfrac{C_{3}}{2}-\dfrac{C_{4}}{2}\right)n-C_{2} = ( 2 C 2 + 2 C 3 + 2 C 4 ) n 2 + ( C 1 + 2 C 2 − 2 C 3 − 2 C 4 ) n − C 2
我们可以表示为:a n 2 + b n + c an^{2}+bn+c a n 2 + b n + c
忽略掉低阶项和最重要的项的常系数时,只剩下重要的项中的因子n 2 n^{2} n 2 ,得出运行时间为Θ ( n 2 ) Θ\left(n^{2}\right) Θ ( n 2 )
与插入算法相比,感觉半斤八两吧
2-3
Θ ( n ) Θ(n) Θ ( n )
该算法的运行时间是Θ ( n ) Θ(n) Θ ( n ) ,与霍纳规矩相比,霍纳规矩的性能更好
Polynomial ( A, n)
1 if n == 0
2 return A[ A. length - n]
3 return A[ A. length - n] + x * Polynomial ( A, n - 1 )
算法导论第二章思考题2-3( ( ( 自己看) ) )
It should be fairly obvious, but the invariant of the loop is a sum that equals a polynomial with the given coefficients.
(这应该是很明显的,但是循环不变式是一个等于给定系数的多项式的和。)
2-4
( 6 , 1 ) 、 ( 8 , 1 ) 、 ( 3 , 1 ) 、 ( 2 , 1 ) 、 ( 8 , 6 ) (6, 1)、(8, 1)、(3, 1)、(2, 1)、(8, 6) ( 6 , 1 ) 、 ( 8 , 1 ) 、 ( 3 , 1 ) 、 ( 2 , 1 ) 、 ( 8 , 6 )
一个递减排好序得数组具有最多得逆序对,具有∑ j = 1 n − 1 t j \sum^{n-1}_{j=1}t_{j} ∑ j = 1 n − 1 t j ,也就是n ( n − 1 ) 2 \dfrac{n\left(n-1\right)}{2} 2 n ( n − 1 ) 个逆序对
算法导论第二章思考题2-4( ( ( 自己看) ) )
算法导论第二章思考题2-4( ( ( 自己看) ) )