求逆序数的三种数据结构比较

本文比较 树状数组,线段树,还有一种unnamed的树状结构,在求逆序数中的运行效率。

给定数组a,如果有i, j, i < j且a[i] > a[j],我们称之为一个逆序(反序),求逆序数即找出这样的i,j对的数目。如果通过交换相邻元素来对数组排序,那么逆序数正好是最少的交换次数。长度为n的排列,其逆序数的期望是n(n-1)/4,方差是n(2n+5)(n-1)/72。逆序数的平均数可以大概视为n^2/4,标准差大概视为(1/6)n^(3/2)。

经典的求逆序数的算法可以由归并排序给出,但是在实现细节上可能会出错。而使用辅助数据结构则使得实现难度降低。

最简单的是用线段树:从左往右扫描,每扫描到一个数时,则通过线段树求出当前线段树上大于当前元素的元素的个数。然后将当前元素加到线段树中。

在这里,上述算法也可以用树状数组(binary index tree)来实现。在添加元素时,从大到小,可以理解为从最小元素到当前元素添加了一根线段。在查询时,从小到大累加,可以理解为求当前元素被多少个线段覆盖,也就是比当前元素大的元素的数量。

还有一种树状结构,对于[l, r]的一个区间,令mid=l+r>>1用tree[mid]来维护[mid, r]上的元素个数。
插入时,如果需要插入的元素正好是mid,则计数加1,算法结束。
如果在[mid+1, r]上,则计数加1,同时递归到右区间:l = mid + 1。
如果在[l, mid-1]上,则tree[
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值