归并排序,从字面上可得知是利用了归并操作的一种排序,同时也是分治法的典型应用,先把问题细分,再整合,听说Windows系统上的文件排序也是采用了归并排序的方法,归并排序是一种稳定的排序方法,因为相同元素的前后顺序在排序后跟原来不变,原因是相同的不做操作。归并排序的时间复杂度在平均情况下是O(nlgn)是一种高效的排序方法。
归并排序的实现采用一下思路,
假如存在以下数组:int a[3]={2,1,3,1}
首先我们把2,1,3
拆分成两部分
2 1 3 1
比较同时合并
12 13
再合并得到
1123
贴上归并操作的代码
inline void mergearry(int arr[],int first,int mid,int last ,int temp[])
{
int i=first;
int j=mid+1;
int m=mid;
int n=last;
int k=0;
//合并两个数组
while(i<=m&&j<=n)
{
if(arr[i]<arr[j])
temp[k++]=arr[i++];
else
temp[k++]=arr[j++];
}
//假如i大于等于j
while(i<=m)
temp[k++]=arr[i++];
while(j<=n)
temp[k++]=arr[j++];
//替换源数组
for(i=0;i<k;i++)
arr[first+i]=temp[i];
}
贴上关键代码:
因为我们需要把数组拆分,因此我们采用的是递归
void Mymergesort(int arry[],int first,int last,int temp[])
{
if(first<last)
{
//递归分离数组
int mid=(last+first)/2;
Mymergesort(arry,first,mid,temp);
Mymergesort(arry,mid+1,last,temp);
mergearry(arry,first,mid,last,temp);
}
}
如果用逻辑上把数组上变成一个二叉树的话,可以看出上方我们采用的是先序遍历的方式访问每个节点。
bool MergeSort(int arr[],int n)
{
int *p=new int[n];
if(p==NULL)
{
printf("error,can not allocate\n");
return false;
}
Mymergesort(arr,0,n-1,p);
delete []p;
return true;
}
根据数组元素的个数生成一个储存的数组。
一下是20000个数据的排序时间