#include<stdio.h>
#include<stdlib.h>
#define bool int
#define true 1
#define false 0
bool Judge_Insertion(int A[],int S[],int N);
void Insertion_Sort(int A[],int N,int p);
int FindMergeLength(int S[],int N);
void Merge_pass(int A[],int TmpA[],int N,int length);
void Merge(int A[],int TmpA[],int L,int R,int RightEnd);
void Merge_Sort(int A[],int N);
int main() {
int i;
int position;
/*--输入数据--*/
int N;
scanf("%d",&N);
int A[N];
int S[N];
for(i=0; i<N; i++) {
scanf("%d",&A[i]);
}
for(i=0; i<N; i++) {
scanf("%d",&S[i]);
}
/*--输入数据结束--*/
/*判断哪种排序*/
if(Judge_Insertion(A,S,N)) { /*如果是插入排序*/
printf("Insertion Sort\n");
for(i=0; i<N; i++) {
if(i==0) printf("%d",S[i]);
else printf(" %d",S[i]);
}
} else {/*如果是归并排序*/
Merge_Sort(S,N);/*求出当前归并段的长度*/
printf("Merge Sort\n");
for(i=0; i<N; i++) {
if(i==0) printf("%d",S[i]);
else printf(" %d",S[i]);
}
}
return 0;
}
bool Judge_Insertion(int A[],int S[],int N) {
int i;
int pos;
for(i=0; i<N-1; i++) { /*先判断是否插入排序*/
if(S[i]>S[i+1]) break;/*从左向右扫描,知道发现顺序不对,跳出循环*/
}
pos=i+1;
for(i=i+1; i<N; i++) {
if(S[i]!=A[i]) return false;
}
if(i>=N) {
Insertion_Sort(S,N,pos);
return true;
}
}
void Insertion_Sort(int S[],int N,int p) {/*仅执行一次的插入排序*/
int Tmp;
int i;
Tmp=S[p];/*取出未排序序列中的第一个元素*/
for(i=p; i>0&&S[i-1]>Tmp; i--)
S[i]=S[i-1];/*依次与已排序序列中元素比较并右移*/
S[i]=Tmp;/*放进合适的位置*/
}
int FindMergeLength(int S[],int N) {
int l;
int i;
for(l=2; l<=N; l*=2) {
for(i=l; i<N; i=i+l*2) {
if(S[i-1]>S[i]) return l;
}
}
}
void Merge_Sort(int A[],int N) {
int length;
int *TmpA;
length=FindMergeLength(A,N);/*初始化子序列长度*/
TmpA=(int *)malloc(N*sizeof(int));
if(TmpA!=NULL) {
/*只执行一次归并*/
Merge_pass(A,TmpA,N,length);
//length*=2;
Merge_pass(TmpA,A,N,length);
//length*=2;
free(TmpA);
} else printf("空间不足");
}
/*length=当前有序子列的长度*/
void Merge_pass(int A[],int TmpA[],int N,int length) {
/*两两归并相邻有序子列*/
int i,j;
for(i=0; i<=N-2*length; i+=2*length)
Merge(A,TmpA,i,i+length,i+2*length-1);
if(i+length<N)/*归并最后2个子列*/
Merge(A,TmpA,i,i+length,N-1);
else/*最后只剩1个子列*/
for(j=i; j<N; j++) TmpA[j]=A[j];
}
/*L=左边起始位置,R=右边起始位置,RightEnd=右边终点位置*/
void Merge(int A[],int TmpA[],int L,int R,int RightEnd) {
/*将有序的A[L]~A[R-1]和A[R]~A[RightEnd]归并成一个有序序列*/
int LeftEnd,NumElements,Tmp;
int i;
LeftEnd=R-1;/*左边终点位置*/
Tmp=L; /*有序序列的起始位置*/
NumElements=RightEnd-L+1;
while(L<=LeftEnd&&R<=RightEnd) {
if(A[L]<=A[R])
TmpA[Tmp++]=A[L++];/*将左边元素复制到TmpA*/
else
TmpA[Tmp++]=A[R++];/*将右边元素复制到TmpA*/
}
while(L<=LeftEnd)
TmpA[Tmp++]=A[L++];/*直接复制左边剩下的*/
while(R<=RightEnd)
TmpA[Tmp++]=A[R++];/*直接复制右边剩下的*/
for(i=0; i<NumElements; i++,RightEnd--)
A[RightEnd]=TmpA[RightEnd];/*将有序的TmpA[]复制回A[]*/
}
09-排序2 Insert or Merge
最新推荐文章于 2022-05-26 11:25:52 发布