转自:
http://blog.csdn.net/yinjiabin/article/details/8265827/
http://www.2cto.com/kf/201407/313489.html
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,归并排序将两个已排序的表合并成一个表。
归并排序基本原理
通过对若干个有序结点序列的归并来实现排序。
所谓归并是指将若干个已排好序的部分合并成一个有序的部分。
归并排序基本思想
设两个有序的子序列(相当于输入序列)放在同一序列中相邻的位置上:array[low..m],array[m + 1..high],先将它们合并到一个局部的暂存序列 temp (相当于输出序列)中,待合并完成后将 temp 复制回 array[low..high]中,从而完成排序。
在具体的合并过程中,设置 i,j 和 p 三个指针,其初值分别指向这三个记录区的起始位置。合并时依次比较 array[i] 和 array[j] 的关键字,取关键字较小(或较大)的记录复制到 temp[p] 中,然后将被复制记录的指针 i 或 j 加 1,以及指向复制位置的指针 p加 1。重复这一过程直至两个输入的子序列有一个已全部复制完毕(不妨称其为空),此时将另一非空的子序列中剩余记录依次复制到 array 中即可。
若将两个有序表合并成一个有序表,称为2-路归并。
举例说明"归并排序的排序过程"
看下面归并排序的两种排序过程
1.待排序列(14,12,15,13,11,16)
假设我们有一个没有排好序的序列,那么首先我们使用分割的办法将这个序列分割成一个个已经排好序的子序列。然后再利用归并的方法将一个个的子序列合并成排序好的序列。分割和归并的过程可以看下面的图例。
先"分割"再"合并"
从上图可以看出,我们首先把一个未排序的序列从中间分割成2部分,再把2部分分成4部分,依次分割下去,直到分割成一个一个的数据,再把这些数据两两归并到一起,使之有序,不停的归并,最后成为一个排好序的序列。
2.待排序列(25,57,48,37,12,92,86)
利用归并排序思想求解逆序对数
题目:给一列数,求它的逆序对数!
分析,由于n可能很大,所以O(n2)的枚举方法肯定超时。所以要用分治的方法!
(1)划分问题:把序列分成元素个数尽量相等的两半。
(2)递归求解:统计i和j均在左边或者均在右边的逆序对个数。
(3)合并问题:统计i在左边,j在右边的逆序对个数。
划分以后,对于右边的每个j,统计左边比它大的元素个数f(j),则所有f(j)之和便是答案。
所以由于我们的归并排序操作是从小到大进行的,当右边的A[j]复制到T中时,左边还没有来得及复制到T的那些数就是左边所有比A[j]大的数。
所以此时在累加器中加上左边元素个数m-p就可以了!