归并排序(MERGE-SORT)
1.当我们要排序这样一个数组的时候,归并排序法首先将这个数组分成一半
2.然后想办法把左边的数组给排序,右边的数组给排序,之后呢再将它们归并起来。
3.当然了当我们对左边的数组和右边的数组进行排序的时候,再分别将左边的数组和右 边的数组分成一半,然后对每一个部分先排序,再归并
4.分到一定细度的时候,每一个部分就只有一个元素了,那么我们此时不用排序,对他们进行一次简单的归并就好了
5.归并到上一个层级之后继续归并,归并到更高的层级,直至最后归并完成。
我们可以开辟一个临时数组来辅助我们的归并。也就是说他比我们插入排序也好,选择排序也好多使用了存储的空间,
也就是说他需要o(n)的额外空间来完成这个排序。只不过现在计算机中时间的效率要比空间的效率重要的多。
无论是内存也好还是硬盘也好可以存储的数据越来越多,所以设计一个算法,时间复杂度是要优先考虑的。
详细图解点击这里
归并排序代码如下:
#include<stdio.h>
#include<string.h>
#define maxn 1000000
long long int a[maxn+5],b[maxn+5];//a表示需要排序的数组,b是临时数组
void merge(int l,int mid,int r) //从小到大排序并将俩部分数组合并
{ //l表示左边的起始位置
int i=l; // mid+1表示右边的起始位置
int j=mid+1;
int k=l;
while(i<=mid&&j<=r)
{
if(a[i]>a[j]){ //从小到大排序
b[k++]=a[j++]; //储存到临时数组中
}
else b[k++]=a[i++];
}
while(i<=mid)b[k++]=a[i++];//将剩余部分存到b数组中
while(j<=r)b[k++]=a[j++];
for(int i=l;i<=r;i++)
a[i]=b[i]; //将排好序且合并好数重新赋值到a数组中
}
void mergesort(int l,int r)
{
if(l<r){
int mid=(l+r)/2;
mergesort(l,mid); //排左边
mergesort(mid+1,r); //拍右边
merge(l,mid,r); //归并
}
}
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
mergesort(0,n-1);
for(int i=0;i<n;i++){
printf("%d ",a[i]);
if(i!=n-1)printf(" ");
}
printf("\n");
}
return 0;
}