题目链接
前言:
这题我做了好久,气人,主要是因为以下的一直过不了
这题就是直接利用插入排序和归并排序。
关键点:
1、首先要充分理解插入排序和归并排序的每一步,插入排序的每步,都是对一个tmp值处理
int InsertSort(ElementType B[], int p)
{
int i;
int tmp = B[p];
for (i=p; i>0&&B[i-1]>tmp; i--)
B[i] = B[i-1];
B[i] = tmp;
return pan(B);
}
p指当前取出tmp值的位置。
然后是归并排序,这里归并排序要用到非递归的方法,其每一个就是选出一个length,然后进行归并排序。
void Merge(ElementType A[], ElementType TmpA[], int L, int R, int RightEnd)
{
int num = RightEnd-L+1;
int LeftEnd = R-1;
int pos=L;
while (L<=LeftEnd&&R<=RightEnd)
{
if (A[L]<A[R])
TmpA[pos++] = A[L++];
else
TmpA[pos++] = A[R++];
}
while (L<=LeftEnd)
TmpA[pos++] = A[L++];
while (R<=RightEnd)
TmpA[pos++] = A[R++];
for (int i=0; i<num; i++,RightEnd--)
A[RightEnd] = TmpA[RightEnd];
}
int Merge_pass(ElementType A[], ElementType TmpA[], int N, int length)
{
int i;
for (i=0; i<N-length*2; i+=length*2)
Merge(A, TmpA, i, i+length, i+length*2-1);
if (i+length<N)
Merge(A, TmpA, i, i+length, N-1);
else
for (int j=i; j<N; j++) TmpA[j] = A[j];
return pan(A);
}
2、主函数中就按照题目意思,一步一步计算看是哪个排序
int j=0;
int length = 1;
int flag = 0;
while (!flag)
{
flag = InsertSort(B, j);
j++;
if (flag)
{
printf("Insertion Sort\n");
InsertSort(B, j);
print(B);
break;
}
flag = Merge_pass(A, TmpA, n, length);
length*=2;
if (flag)
{
printf("Merge Sort\n");
Merge_pass(A, TmpA, n, length);
print(A);
break;
}
}
提交一看,
是InsertSort出了问题,输入
1
1
1?
输出
1 1 1 Insertion Sort 0?
这就很不对了,分析,从
j=0 开始,插入排序一次,第一次数组不变得到和所给的数组相匹配,因此输出InsertSort,之后再进行一次插入排序,因为我数组开的是110个大小,导致存在下标为1的数为0,导致插入后数组变为
B[0] = 0, B[1] = 1,0是本来不存在与数组里的,但是我遍历输出时还是按数组大小来输出,因此输出0.
所以这里要将j改为从1开始,进行插入排序
改了我真的好久,哎。。。
完整代码:
# include<stdio.h>
# include <stdlib.h>
# define ElementType int
int n;
int ans[110];
int pan(ElementType A[])
{
for (int i=0; i<n; i++)
{
if (A[i]!=ans[i])
return 0;
}
return 1;
}
void print(ElementType A[])
{
printf("%d", A[0]);
for (int i=1; i<n; i++)
printf(" %d", A[i]);
printf("\n");
}
int InsertSort(ElementType B[], int p)
{
int i;
int tmp = B[p];
for (i=p; i>0&&B[i-1]>tmp; i--)
B[i] = B[i-1];
B[i] = tmp;
return pan(B);
}
void Merge(ElementType A[], ElementType TmpA[], int L, int R, int RightEnd)
{
int num = RightEnd-L+1;
int LeftEnd = R-1;
int pos=L;
while (L<=LeftEnd&&R<=RightEnd)
{
if (A[L]<A[R])
TmpA[pos++] = A[L++];
else
TmpA[pos++] = A[R++];
}
while (L<=LeftEnd)
TmpA[pos++] = A[L++];
while (R<=RightEnd)
TmpA[pos++] = A[R++];
for (int i=0; i<num; i++,RightEnd--)
A[RightEnd] = TmpA[RightEnd];
}
int Merge_pass(ElementType A[], ElementType TmpA[], int N, int length)
{
int i;
for (i=0; i<N-length*2; i+=length*2)
Merge(A, TmpA, i, i+length, i+length*2-1);
if (i+length<N)
Merge(A, TmpA, i, i+length, N-1);
else
for (int j=i; j<N; j++) TmpA[j] = A[j];
return pan(A);
}
int main()
{
scanf("%d", &n);
int A[110];
int B[110];
int TmpA[110];
for (int i=0; i<n; i++)
{
scanf("%d", &A[i]);
B[i] = A[i];
}
for (int i=0; i<n; i++)
scanf("%d", &ans[i]);
int j=0;
int length = 1;
int flag = 0;
while (!flag)
{
flag = InsertSort(B, j);
j++;
if (flag)
{
printf("Insertion Sort\n");
InsertSort(B, j);
print(B);
break;
}
flag = Merge_pass(A, TmpA, n, length);
length*=2;
if (flag)
{
printf("Merge Sort\n");
Merge_pass(A, TmpA, n, length);
print(A);
break;
}
}
return 0;
}
?
|