归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

时间复杂度:O(n*logn)
空间复杂度:T(n)
稳定性:稳定

归并操作的工作原理如下:
第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置
第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针超出序列尾
将另一序列剩下的所有元素直接复制到合并序列尾

我们需要做的就是需要开辟两个空间 先分而治之,分而治之保证了每个子序列都是有序的,然后在进行归并的时候就可以保证当前序列的最小值放进了序列之中。

#include <iostream>
#include <bits/stdc++.h>

using namespace std;
const int N = 1e6+10;
int a[N],temp[N],n;

void merge_sort(int *a,int l,int r)
{
    if(l >= r)
        return ;
    int mid = (l+r)>>1;
    merge_sort(a,l,mid);//先分治
    merge_sort(a,mid+1,r);
    int i = l,j = mid+1;
    int k = 0;
    while(i <= mid && j <=r)
    {
        if(a[i] <= a[j])
            temp[k++] = a[i++];
        else
            temp[k++] = a[j++];
    }
    while(i <= mid)//将没有选完的序列直接存入temp数组之中
        temp[k++] = a[i++];
    while(j <= r)
        temp[k++] = a[j++];
    for(int i = l,j = 0;i <= r;i++,j++)//后归并
        a[i] = temp[j];//将temp里面的序列拿到a数组中进行输出
}

int main()
{
    scanf("%d",&n);
    for(int i = 0;i < n;i++)
    {
        scanf("%d",&a[i]);
    }

    merge_sort(a,0,n-1);

    for(int i = 0;i < n;i++)
        printf("%d ",a[i]);
    return 0;
}