内部排序—— 第5波 ——————【归并排序】

归并排序是一种利用分治思想的排序方法。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。归并排序还是一种稳定的排序方法。所需空间复杂度为O(n)。时间复杂度为O(nlogn)。

 

//归并排序
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn = 1e3+200;
void Merge(int sorce[],int tmp[],int s,int m,int t){
    int i, j, k;
    //i为第一部分的指针、j为第二部分的指针、k为辅助数组的指针
    for(i = s, j = m+1, k = s; i <= m&&j <= t; k++){
        if(sorce[i] < sorce[j]){
            tmp[k] = sorce[i++];
        }else{
            tmp[k] = sorce[j++];
        }
    }
    if(i <= m){ //第二部分全部写入辅助数组,第一部分有剩余
        for(; i <= m; i++){
            tmp[k] = sorce[i]; k++;
        }
    }
    if(j <= t){ //第一部分全部写入辅助数组,第二部分有剩余
        for(; j <= t; j++){
            tmp[k] = sorce[j]; k++;
        }
    }
    for(i = s; i <= t; i++){    //写回原数组
        sorce[i] = tmp[i];
    }
}
void MergeSort(int sorce[],int tmp[],int s,int t){
    if(s == t){
        tmp[s] = sorce[s];
    }else{
        int m = (s+t)/2;
        MergeSort(sorce,tmp,s,m);   //将sorce[s...m]有序地归并到tmp[s...m]中
        MergeSort(sorce,tmp,m+1,t); //将sorce[m+1...t]有序地归并到tmp[m+1...t]中
        Merge(sorce,tmp,s,m,t); //将tmp[s...m]和tmp[m+1...t]归并到sorce[s...t]中
    }
}
int main(){
    int a[maxn],b[maxn];
    int n;
    while(scanf("%d",&n)!=EOF){
        for(int i = 1; i <= n; i++){
            scanf("%d",&a[i]);
        }
        MergeSort(a,b,1,n);
        for(int i = 1; i <= n; i++){
            printf("%d ",b[i]);
        }
    }
    return 0;
}

  

归并排序求逆序数:

//求逆序数
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
typedef long long LL;
const int maxn = 1e6+300;
int a[maxn], b[maxn];
LL Merge(int L,int M,int R){
    LL ret = 0;
    int i, j, k = L;
    for(i = L, j = M+1; i<=M&&j<=R; k++){
        if(a[i] > a[j]){
            ret += (M-i+1);
            b[k] = a[j]; j++;
        }else{
            b[k] = a[i]; i++;
        }
    }
    if(i <= M){
        for( ; i <= M; i++){
            b[k] = a[i]; k++;
        }
    }
    if(j <= R){
        for( ; j <= R; j++){
            b[k] = a[j]; k++;
        }
    }
    for(i = L; i <= R; i++){
        a[i] = b[i];
    }
    return ret;
}
LL Merge_sort(int L,int R){
    LL ret = 0;
    if(L == R) return ret;
    int mid = (L+R)/2;
    ret += Merge_sort(L,mid);
    ret += Merge_sort(mid+1,R);
    ret += Merge(L,mid,R);
    return ret;
}

int main(){
    int cas, n;
    scanf("%d",&cas);
    while(cas--){
        scanf("%d",&n);
        for(int i = 1; i <= n; i++){
            scanf("%d",&a[i]);
        }
        LL res = Merge_sort(1,n);
        printf("%lld\n",res);
    }
    return 0;
}

  

posted @ 2016-04-07 17:47  tcgoshawk  阅读(196)  评论(0编辑  收藏  举报