逆序对

 

2-4 逆序对

      设A[1...n]是一个包含n个不同数的数组,如果在i<j的情况下,有A[i]>A[j],则(i,j)就称为A中的一个逆序对(inversion)。

       a)列出数组<2, 3, 8, 6, 1>的5个逆序对

       b)如果数组的元素取自集合{1,2,...,n}, 那么, 怎样的数组含有最多的逆序对?它包含多少个逆序对?

       c)插入排序的运行时间与输入数组中逆序对的数量之间有怎样的关系?说明你的理由。

       d)给出一个算法,它能用Θ(nlgn)的最坏情况运行时间,确定n个元素的任何排列中逆序对的个数。(提示:修改合并排序)

 

 

分析与解答:

      对于数组A[1...n],如果要确定所有的逆序对,只需要遍历一次数组,对于以A[j]结尾的逆序只需要遍历所有1<= i <=j

若满足A[i] > a[j],则说明(i,j)是一个逆序对,否则不是。这是一种非常朴素的方法,整个算法的时间复杂度为Θ(n*n)

 

a)  采用类似上面的方法,以6结尾逆序对有(1,4),以1结尾的逆序对有(1,5),(2,5),(3,5),(4,5),总共为5个

 

b)  当整个数组完全逆序时,含有最多的逆序对,即A={n,...,2,1},这时

   以n-1结尾的逆序对有1个,以n-2结尾的逆序对有2个,以此类推,以1结尾的逆序对有n-1个。

   总共(n-1)+(n-2)+...1 = n(n-1)/2

 

c)  插入排序的运行时间与插入排序时的总的比较次数相关,而总共的比较次数与总的逆序对的个数相同。因此两者成正比

在插入排序的过程中,插入A[j]需要比较的次数和已排序的A[1...j-1]中比A[j]大的元素个数相同,这等价于逆序对的个数。

 

d)  合并排序是采用分治法的思想,若需要排序A[p...q],则可以对半分成A[p...r]和A[r...q],然后将这有序的两部分Merge。

    而Merge的过程为Θ(n)的时间复杂度

   根据主定率T(n)=2(Tn/2)+Θ(n),时间复杂度为T(n)=Θ(nlgn)。

 

   而求整个序列中的逆序对,也可以利用分治法的思想,即

   逆序对(A[p...q])= 逆序对(A[p...r])+逆序对(A[r...q])+逆序对(A[p...r], A[r...q]之间的)

   结合合并排序,关键是求如何在Θ(n)的时间有效的求出A[p...r], A[r...q]之间的逆序对

   因为在合并排序的Merge过程中,A[p...r]和A[r...q]已经有序,假设此时已经Merge到A[s...r]和A[t...q]。考虑接下来的一步:若从前者取出A[s],说明A[s]比后面的序列A[t...q]中的元素都小,不存在逆序对;若从后者取出A[t],则说明A[t]比前面的序列A[s...r]都小,即以t结尾的逆序对的数量为前者的剩余序列A[s...r]中元素的数量

   Merge的过程中即可得到A[p...r], A[r...q]之间的逆序对的数量,时间复杂度亦为Θ(n), 由主定律总的时间复杂为 Θ(nlgn),这种方法要比朴素的方法 Θ(n*n)好很多。

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值