説明
[説明]
1,2,4の区間長Lをしてみましょう、... 2 ^(N- 1)
とIマージソート方法などの各位置のための順序付きマージセクションの最初の長さL、その後は私をジャンプ私はL +に行く
複雑さを書いている時点のいくつかの詳細に注意を払う、まだLOG2(N)* n個のレベルです。
たとえば、= N>の最終的なケースLを行わせることを確認し、または全配列が順序付けされることを保証することができません
[コード]
/*
归并排序非递归写法
*/
#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;
}