从0开始学算法--排序(1.5归并排序)

Posted wz-archer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从0开始学算法--排序(1.5归并排序)相关的知识,希望对你有一定的参考价值。

算法理解:

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

如n=6,m=3

1 3 5 2 4 6
1 2 3 4 5 6

排序前

排序后

 

 

#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("
");
    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("
");
    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
",cnt);
    return 0;
}

 

以上是关于从0开始学算法--排序(1.5归并排序)的主要内容,如果未能解决你的问题,请参考以下文章

用分解的方式学算法004——归并排序

十大经典排序算法总结(归并排序)

排序算法总结-选择排序插入排序归并排序和快速排序

排序问题之归并排序

归并排序-PHP版

看动画学算法之:排序-归并排序