相对插入排序 归并排序的复杂度可以降到O(nlogn)
采用divide and conquer思想 将组数分成两组,若设两组数都是已经排好序(从小到大),则可在O(n)时间内合并两个数组为一个数组,并排好序
运用递归方法来实现
merge(data[ ], p, q, r)
Ldata[0……n1] = data[p……q]
Rdata[0……n2] = data[q+1……r]
将Ldata[ ] Rdata[ ] 合并为一个组数据(假设两者都排好序)
从p to r
依次从Ldata 和 Rdata中选择较小者赋值给data 直到两者遍历完
/*******merge sorting******/
#define sentinel 10000
void merge_fun(int data[],int p,int q,int r)// to merge two sorted array
{
int n1=q-p+1;
int n2=r-q;
int i;
int j;
int *ldata=(int*)malloc(sizeof(int)*(n1+1)); //malloc memory
int *rdata=(int*)malloc(sizeof(int)*(n2+1)); //copy data
for(i=0;i<n1;i++)
ldata[i]=data[p+i];
for(i=0;i<n2;i++)
rdata[i]=data[q+1+i];
ldata[n1]=sentinel; //the sentinel is to simplify code
rdata[n2]=sentinel;
i=0,j=0;
for(int k=p;k<=r;k++) //merge two array
{
if (ldata[i]>rdata[j]) //get min(ldata,rdata) then assign it to data[k]
data[k]=rdata[j++];
else
data[k]=ldata[i++];
}
free(ldata); //free memory
free(rdata);
}
//接下来 可以运用递归方法完成合并排序
void merge_sort(int data[],int p,int r) //sorting by recursion method
{
int q;
if (p<r)
{
q=(p+r)/2;
merge_sort(data,p,q); //sort left
merge_sort(data,q+1,r);//sort right
merge_fun(data,p,q,r);//merge left and right
}
}
效率分析:
根据递归分析法 T(n)= c n=1;
T(n) = 2T(n/2) +c*n n>1;
其中c*n 是merge_fun函数的时间复杂度 这是最基本操作 即为O(n)
取对数可得 T(n) = nlogn
值得注意的是merge_fun函数中 sentinel 变量只是为了简化合并部分的代码 别无它用,其取值可以看出无穷大 此处设为10000,若在增加几行代码 则
可以去除sentinel