题目:
求逆序对
解答:
a) 列出数组<2,3,8,6,1> 的五个逆序对
<8,6 > <8,1 > <6,1 > <3,1 > <2,1 >
b) 如果数组的元素取自集合 {1,2,3,4,......,n} 怎样的数组还有最多的逆序对,它包含多少个逆序对
逆序序列 {n,n−1,n−2,n−3,......,1} 含有 (n−1)n/2 个逆序对
c) 插入排序的运行时间与输入数组中逆序对的数量之间有怎样的关系?
仔细观察会发现实际上,计算逆序对就是插入排序的比较过程,所以数量级一样,但是不用移动元素,具体时间会短些
d) 在 Θ(nlgn) 的最坏情况运行时间,确定n个元素任何排列中的逆序对数目
有了提示后这个题就很简单了,归并排序过程中每次将两个子序列归并成一个子序列的过程中,如果左边的序列当指针指向的元素大于右边的指针指向的元素,计数就自增,归并完成后就是你序列数目。
原理也很简单,逆序列就是左边比右边大的数据对,而归并排序正是把这样的数据对调整过来的过程,其实不仅仅是这样,这里可以思考另一个过程,如果我们把归并换成快排,快排的每次排序也是把左大右小的数据对调整过来,实际上基于比较的排序都是这样,但是快排是错误的比如序列 {4,3,2,1} 就明显不对,其实问题就出在快排每趟排序会破坏原序列的整体关系,比如第一趟排序过后会变成 {1,3,2,4} 这里破坏了1和2,3的逆序关系,而归并排序恰恰有从局部开始,不破坏整体关系的优点
所以归并排序的正确性就在于:1 正好是调整逆序数对的过程,2 不破坏数列的整体关系