将已有的子序列比较合并,得到完全有序的序列。
归并过程:比较有序序列a[i]和b[j]的大小,若a[i]<=b[j],则将a[i]复制到新序列空间r[k]中,i++,k++。否则将b[j]复制到r[k],j++,k++.如此循环,直到其中一个序列取完,然后将剩下那个序列的所有值复制到r[k]即可。
优点:
归并是稳定的排序,相等的元素的顺序不会改变,这也是比快速排序优势的地方。而速度也仅次于快速排序
用途:
一般用于对总体无序,但是各子序列有序的数列。
c/c++语言实现:
#include <stdio.h>
#include <stdlib.h>
void merge(int sourceArr, int tempArr, int middleIndex, int startIndex, int endIndex){
int i=startIndex;
int k=startIndex;
int j=middleIndex+1;
while(i!=middleIndex+1 && j!=endIndex+1){
if(sourceArr[i]>sourceArr[j])
tempArr[k++]=sourceArr[j++];
else
tempArr[k++]=sourceArr[i++];
}
while(i!=middleIndex+1)
tempArr[k++]=sourceArr[i++];
while(j!=endIndex+1)
tempArr[k++]=sourceArr[j++];
for(i=startIndex;i<=endIndex;i++)
sourceArr[i]=tempArr[i];
}
void mergesort(int sourceArr[], int tempArr[], int startIndex, int endIndex){
int middleIndex;
if(startIndex<endIndex){
middleIndex=(startIndex+endIndex)/2;
mergesort(sourceArr, tempArr, startIndex, middleIndex);//使用递归对左右两个子序列进行排序
mergesort(sourceArr, tempArr, middleIndex+1, endIndex);
merge(sourceArr, tempArr, middleIndex, startIndex, endIndex);//排序完成后进行合并
}
}
int main()
{
int a[8]={10, 40, 50, 20, 15, 60, 70, 5};
int i, b[8];
mergesort(a, b, 0 , 7);
for(i=0;i<=7;i++){
printf("%d\n",a[i] );
}
return 0;
}
经典算法题:
求逆序对数
思路:在归并过程中计算每个小区间的逆序对数,进而计算出大区间的逆序对数。