快排——归并排序

归并排序(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;
}

猜你喜欢

转载自blog.csdn.net/qq_43328040/article/details/87614577