[Book] to explain the non-recursive merge sort of wording

description

【answer】


Let the interval length L of 1,2,4, ... 2 ^ (n- 1)
and i the length L of the beginning of the ordered merge section for each position, like merge sort method, and then jump i go to i + L
complexity is still log2 (n) * n level, pay attention to some details of the time of writing.
For example, be sure to let conducted a final case L = n of>, or can not ensure that the entire sequence is ordered

[Code]

/*
    归并排序非递归写法
*/
#include <cstdio>
const int N = 1e5;

int a[N+10],b[N+10];
int n;

//把a这个数组在l1..r2这个区间分成两段[l1,r1]和[l2,r2];然后进行合并
void _Merge(int a[],int b[],int l1,int r1,int l2,int r2){
    int i = l1,j = l2,k = l1;
    while (i<=r1 && j<= r2){
        if (a[i]<=a[j])
            b[k++]=a[i++];
        else
            b[k++] = a[j++];
    }
    while (i<=r1) b[k++] = a[i++];
    while (j<=r2) b[k++] = a[j++];
}

void _merge(int a[],int b[],int L){
    int i = 1;
    while (i+L-1<n){//把i..i+L-1这个区间合并
        _Merge(a,b,i,i+L/2-1,i+L/2,i+L-1);
        i = i+L;
    }
    //i+L-1>=n
    if (i+L/2-1<=n){
        _Merge(a,b,i,i+L/2-1,i+L/2,n);
    }else{
        _Merge(a,b,i,n,n+1,n);
    }
}

int main(){
    //freopen("D:\\rush.txt","r",stdin);
    scanf("%d",&n);
    for (int i = 1;i <= n;i++) scanf("%d",&a[i]);
    int L = 1;
    while (L<=n){
        L*=2;
        _merge(a,b,L);//把a长度为L的合并起来然后放到b数组中去
        L*=2;//要确保L>n的时候,那个长度合并过
        _merge(b,a,L);//把b长度为L的合并起来然后放到a数组中去
    }
    for (int i = 1;i <= n;i++) printf("%d ",a[i]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/AWCXV/p/11620700.html