由二分法,一个初始数列最终会被分成 n 个单个项,相当于 n 个排好序的数列。

 

对于已排好序的两个子数列,长度分别为L1,L2,每一次比较两个数列剩余项中的首项,并将较大项或较小项整合进入原数列,并从相应子数列中剔除,则最多经过L1+L2次比较,可以将原数列对应区段完成单调排序。

 

模板一:

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
void merge(int x[],int left,int mid,int right)
{
    int temp1[5005],temp2[5005];
    int n1=mid-left;
    int n2=right-mid;
    for(int i=0;i<n1;i++) temp1[i]=x[left+i];
    for(int i=0;i<n2;i++) temp2[i]=x[mid+i];
    temp1[n1]=500000;
    temp2[n2]=500000;
    int i=0,j=0;
    for(int k=left;k<right;k++)
        if(temp1[i]<=temp2[j]) x[k]=temp1[i++];
        else x[k]=temp2[j++];
}
void msort(int x[],int left,int right)  //  right = a + 1
{
    if(left+1<right)
    {
        int mid=(left+right)/2;
        msort(x,left,mid);
        msort(x,mid,right);
        merge(x,left,mid,right);
    }
}
int main()
{
    int a;
    a=read();
    int n[a];
    for(int i=0;i<a;i++) n[i]=read();
    msort(n,0,a);
    for(int i=0;i<a;i++)
    {
        if(i) cout<<" ";
        cout<<n[i];
    }
    return 0;
}
merge sort

 

模板二(2021/2/3 update):

(其中ans是记录数列中逆序对个数)

#include<iostream>
#include<cstdio>
using namespace std;
const int range=5e5+5;
int n[range];
long long ans;
int temp1[range],temp2[range];

void msort(int l,int r)
{
    int mid=(l+r)>>1;
    if(l==r) return ;
    else
    {
        msort(l,mid);
        msort(mid+1,r);
    }
    int l1=l,l2=mid+1;
    for(int i=l;i<=mid;i++)
        temp1[i]=n[i];
    for(int i=mid+1;i<=r;i++)
        temp2[i]=n[i];
    int i;
    for(i=l;l1<=mid&&l2<=r;i++)
        if(temp1[l1]>temp2[l2])
        {
            ans+=mid-l1+1;
            n[i]=temp2[l2];
            l2++;
        }
        else
        {
            n[i]=temp1[l1];
            l1++;
        }
    while(l1<=mid)
        n[i++]=temp1[l1++];
    while(l2<=r)
        n[i++]=temp2[l2++];
}
int main()
{
    int a;
    scanf("%d",&a);
    for(int i=1;i<=a;i++) scanf("%d",&n[i]);
    msort(1,a);
    cout<<ans;
    return 0;
}
merge sort