算法导论 — 思考题2-4 逆序对

逆序对)假设 A [ 1.. n ] A[1..n] A[1..n]是一个有 n n n个不同数的数组。若 i < j i < j i<j A [ i ] > A [ j ] A[i] > A[j] A[i]>A[j],则对偶 ( i , j ) (i, j) (i,j)称为A的一个逆序对(inversion)。
  a. 列出数组 < 2 , 3 , 8 , 6 , 1 > <2, 3, 8, 6, 1> <2,3,8,6,1>的5个逆序对。
  b. 由集合 1 , 2 , … , n {1, 2, …, n} 1,2,,n中的元素构成的什么数组具有最多的逆序对?它有多少逆序对?
  c. 插入排序的运行时间与输入数组中逆序对的数量之间是什么关系?证明你的回答。
  d. 给出一个确定在 n n n个元素的任何排列中逆序对数量的算法,最坏情况需要 Θ ( n l g n ) Θ(n{\rm lg}n) Θ(nlgn)时间。(提示:修改归并排序)
  
  a.
  5个逆序对: ( 8 , 6 ) ( 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)
  
  b.
  逆序对最多的情况出现在元素按降序排列的时候,即 n , n − 1 , … , 2 , 1 {n, n-1, … , 2, 1} n,n1,,2,1。这种情况下,任意两个元素都构成逆序对,一共有 C n 2 = ( n ( n − 1 ) ) / 2 C_n^2=(n(n-1))/2 Cn2=(n(n1))/2组逆序对。

c.
  插入排序的运行时间 T ( n ) T(n) T(n)与数组中的逆序对数量 R ( n ) R(n) R(n)成线性关系,即 T ( n ) = Θ ( R ( n ) ) T(n) = Θ(R(n)) T(n)=Θ(R(n))。下面用数学归纳法证明。
  初始情况 n = 2 n = 2 n=2,线性关系显然成立。
  下面进入归纳过程。假设对于 n − 1 n-1 n1个元素的情况,插入排序的运行时间 T ( n − 1 ) T(n-1) T(n1)与逆序对的数量 R ( n − 1 ) R(n-1) R(n1)成线性关系 T ( n − 1 ) = Θ ( R ( n − 1 ) ) T(n-1) = Θ(R(n-1)) T(n1)=Θ(R(n1))。对于 n n n个元素的情况,其逆序对数目 R ( n ) R(n) R(n)分为两部分:
  ① 前 n − 1 n-1 n1个元素的逆序对数目 R ( n − 1 ) R(n-1) R(n1)
  ② 前 n − 1 n-1 n1个元素与第 n n n个元素构成的逆序对数目 R p ( n ) R_p(n) Rp(n)
  故 R ( n ) = R ( n − 1 ) + R p ( n ) R(n) = R(n-1) + R_p(n) R(n)=R(n1)+Rp(n)
   n n n个元素的插入排序可分为两步进行:
  ① 首先将前 n − 1 n-1 n1个元素排序,其时间 T ( n − 1 ) = Θ ( R ( n − 1 ) ) T(n-1) = Θ(R(n-1)) T(n1)=Θ(R(n1))
  ② 然后将第 n n n个元素插入到已排序好的前 n − 1 n-1 n1个元素中。前 n − 1 n-1 n1个元素与第 n n n个元素存在 R p ( n ) R_p(n) Rp(n)个逆序对,这说明前 n − 1 n-1 n1个元素中一共存在 R p ( n ) R_p(n) Rp(n)个元素比第 n n n个元素要大。插入排序在这一阶段要将第 n n n个元素插入到合适的位置,这一步的运行时间 T p ( n ) = Θ ( R p ( n ) ) T_p(n) = Θ(R_p(n)) Tp(n)=Θ(Rp(n))
  故排序 n n n个元素的运行时间 T ( n ) = T ( n − 1 ) + T p ( n ) = Θ ( R ( n − 1 ) ) + Θ ( R p ( n ) ) = Θ ( R ( n − 1 ) + R p ( n ) ) = Θ ( R ( n ) ) T(n) = T(n-1) + T_p(n) = Θ(R(n-1)) + Θ(R_p(n)) = Θ(R(n-1) + R_p(n)) = Θ(R(n)) T(n)=T(n1)+Tp(n)=Θ(R(n1))+Θ(Rp(n))=Θ(R(n1)+Rp(n))=Θ(R(n))
  综上所述,插入排序的运行时间 T ( n ) T(n) T(n)与数组中的逆序对数量 R ( n ) R(n) R(n)成线性关系 T ( n ) = Θ ( R ( n ) ) T(n) = Θ(R(n)) T(n)=Θ(R(n))

d.
  采用分治法。对于数组 A [ 1.. n ] A[1 .. n] A[1..n],将其对半分为两个子数组: A L = A [ 1.. ⌊ n / 2 ⌋ ] A_L = A[1 .. ⌊n/2⌋] AL=A[1..n/2] A R = A [ ⌊ n / 2 ⌋ + 1.. n ] A_R = A[⌊n/2⌋+1 .. n] AR=A[n/2+1..n] A [ 1.. n ] A[1 .. n] A[1..n]的逆序对数目 R ( A ) R(A) R(A)分为 3 3 3部分:
  ① 左半边子数组 A L A_L AL的逆序对数目 R ( A L ) R(A_L) R(AL)
  ② 右半边子数组 A R A_R AR的逆序对数目 R ( A R ) R(A_R) R(AR)
  ③ 左半边子数组的元素与右半边子数组的元素构与的逆序对数目 R ( A L , A R ) R(A_L, A_R) R(AL,AR)
  故 R ( A ) = R ( A L ) + R ( A R ) + R ( A L , A R ) R(A) = R(A_L) + R(A_R) + R(A_L, A_R) R(A)=R(AL)+R(AR)+R(AL,AR)
  下面考虑③。一种简单的方法是,对 A L A_L AL中的每个元素 A L [ i ] A_L[i] AL[i],遍历 A R A_R AR中的每个元素 A R [ j ] A_R[j] AR[j],寻找与 A L [ i ] A_L[i] AL[i]构成逆序对的元素。这种方法的时间为 Θ ( ( n / 2 ) 2 ) = Θ ( n 2 ) Θ((n/2)^2) = Θ(n^2) Θ((n/2)2)=Θ(n2),时间成本太高。然而,如果 A L A_L AL A R A_R AR分别已经排好序,可以把时间缩减到 Θ ( n ) Θ(n) Θ(n)。并且,分别排序 A L A_L AL A R A_R AR并不影响 A L A_L AL A R A_R AR之间的逆序对数目 R ( A L , A R ) R(A_L, A_R) R(AL,AR)。这一过程具体如下:
  在这里插入图片描述
  上述方法可以和归并排序揉合在一起,先执行 C R O S S − I N V E R S I O N − C O U N T ( A , p , q , r ) {\rm CROSS-INVERSION-COUNT}(A, p, q, r) CROSSINVERSIONCOUNT(A,p,q,r),然后执行归并排序的 M E R G E {\rm MERGE} MERGE过程。在递归的每一层,执行 C R O S S − I N V E R S I O N − C O U N T ( A , p , q , r ) {\rm CROSS-INVERSION-COUNT}(A, p, q, r) CROSSINVERSIONCOUNT(A,p,q,r) M E R G E {\rm MERGE} MERGE过程各花费 Θ ( n ) Θ(n) Θ(n)时间。递归一共有 Θ ( l g n ) Θ({\rm lg}n) Θ(lgn)层,因此该算法的执行时间为 Θ ( n l g n ) Θ(n{\rm lg}n) Θ(nlgn)。下面给出完整的伪代码。
  在这里插入图片描述
  代码链接:https://github.com/yangtzhou2012/Introduction_to_Algorithms_3rd/tree/master/Chapter02/Problem_2-4/InversionCount

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值