算法理解:

  一个数组长度为n,他的前m个元素是升序的,后n-m个元素升序的,怎么使整个数组变成一个升序数组?

如n=6,m=3

135246
123456

排序前

排序后

#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>

using namespace std;

const int maxn=1e5+1;
int A[maxn];
int T[maxn];//辅助数组。

int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        scanf("%d",&A[i]);
    }
    int p=0,q=m,i=0;
    while(p<m||q<n){
        if(q>=n||(p<m&&A[p]<=A[q]))T[i++]=A[p++];
        else T[i++]=A[q++];
    }
    for(int i=0;i<n;i++){
        A[i]=T[i];
    }
    for(int i=0;i<n;i++){
        printf("%d ",A[i]);
    }
    printf("\n");
    return 0;
}

归并排序采用了分治的想法,一个数组如果左边有序,右边有序则进行合并,如果左边无序递归处理,同理右边也递归处理。

由于归并排序每次使严格二分,所以时间复杂度是O(nlogn)

#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>

using namespace std;

const int maxn=1e5+1;
int n;
int A[maxn];
int T[maxn];//辅助数组。

void merge_sort(int *A,int x,int y,int *T){
    if(y-x>1){
        int m=x+(y-x)/2;
        int p=x,q=m,i=x;
        merge_sort(A,x,m,T);
        merge_sort(A,m,y,T);
        while(p<m||q<y){
            if(q>=y||(p<m&&A[p]<=A[q]))T[i++]=A[p++];
            else T[i++]=A[q++];
        }
        for(int i=x;i<y;i++){
            A[i]=T[i];
        }
    }
}

int main(){
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&A[i]);
    }
    merge_sort(A,0,n,T);
    for(int i=0;i<n;i++){
        printf("%d ",A[i]);
    }printf("\n");
    return 0;
}

例一:求逆序对对数

#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>

using namespace std;

const int maxn=1e5+1;
int n;
int A[maxn];
int T[maxn];//辅助数组。
int cnt;
void merge_sort(int *A,int x,int y,int *T){
    if(y-x>1){
        int m=x+(y-x)/2;
        int p=x,q=m,i=x;
        merge_sort(A,x,m,T);
        merge_sort(A,m,y,T);
        while(p<m||q<y){
            if(q>=y||(p<m&&A[p]<=A[q]))T[i++]=A[p++];
            else T[i++]=A[q++],cnt+=m-p;
        }
        for(int i=x;i<y;i++){
            A[i]=T[i];
        }
    }
}

int main(){
    scanf("%d",&n);
    cnt=0;
    for(int i=0;i<n;i++){
        scanf("%d",&A[i]);
    }
    merge_sort(A,0,n,T);
    printf("%d\n",cnt);
    return 0;
}
02-13 22:14