Problem Description
According to Wikipedia:
Insertion sort iterates, consuming one input element each repetition, and growing a sorted output list. Each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there. It repeats until no input elements remain.
Merge sort works as follows: Divide the unsorted list into N sublists, each containing 1 element (a list of 1 element is considered sorted). Then repeatedly merge two adjacent sublists to produce new sorted sublists until there is only 1 sublist remaining.
Now given the initial sequence of integers, together with a sequence which is a result of several iterations of some sorting method, can you tell which sorting method we are using?
Input Specification
Each input file contains one test case. For each case, the first line gives a positive integer N (≤100). Then in the next line, N integers are given as the initial sequence. The last line contains the partially sorted sequence of the N numbers. It is assumed that the target sequence is always ascending. All the numbers in a line are separated by a space.
Output Specification
For each test case, print in the first line either "Insertion Sort" or "Merge Sort" to indicate the method used to obtain the partial result. Then run this method for one more iteration and output in the second line the resuling sequence. It is guaranteed that the answer is unique for each test case. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line.
Sample Input 1
10
3 1 2 8 7 5 9 4 6 0
1 2 3 7 8 5 9 4 6 0
Sample Output 1
Insertion Sort
1 2 3 5 7 8 9 4 6 0
Sample Input 2
10
3 1 2 8 7 5 9 4 0 6
1 3 2 8 5 7 4 9 0 6
Sample Output 2
Merge Sort
1 2 3 8 4 5 7 9 0 6
Solution
题意理解:给出待排序数组和排序过程中迭代到某一步之后的顺序,要求这个顺序是由插入排序生成的还是归并排序生成的,并且输出再迭代一次后的顺序。
归并排序:由于这里需要每迭代一次判断是否与所给数组相同,所以需要用非递归算法
归并排序具有稳定性,缺点是需要额外空间,不适合做内部排序,适合做外部排序。
有一个地方需要注意,此题归并函数的迭代是每 MergePass 就是一次迭代,只是为了保证最后的结果重新导回 A 数组,所以每次循环中有两次 MergePass 。
#include <stdio.h>
#include <stdlib.h>
int IsSame(int A[], int N, int target[])
{
int i, flag = 1;;
for (i = 0; i < N && flag; i++)
if (A[i] != target[i]) flag = 0;
return flag;
}
int InserstionSort(int A[], int N, int target[])
{
int i, p, tmp, flag = 0;
int a[100];
for (i = 0; i < N; i++) a[i] = A[i];
for (p = 1; p < N && flag == 0; p++) {
tmp = a[p];
for (i = p; i > 0 && a[i - 1] > tmp; i--)
a[i] = a[i - 1];
a[i] = tmp;
if (IsSame(a, N, target)) flag = 1;
}
if (flag) {
tmp = a[p];
for (i = p; i > 0 && a[i - 1] > tmp; i--)
a[i] = a[i - 1];
a[i] = tmp;
printf("Insertion Sort\n");
for (i = 0; i < N; i++)
if (i) printf(" %d", a[i]);
else printf("%d", a[i]);
}
return flag;
}
void Merge1(int A[], int TmpA[], int L, int R, int REnd)
{
int i, p, LEnd;
LEnd = R - 1;
p = L;
while (L <= LEnd && R <= REnd) {
if (A[L] <= A[R]) TmpA[p++] = A[L++];
else TmpA[p++] = A[R++];
}
while (L <= LEnd) TmpA[p++] = A[L++];
while (R <= REnd) TmpA[p++] = A[R++];
}
void MergePass(int A[], int TmpA[], int N, int length)
{
int i, j;
for (i = 0; i <= N - length * 2; i += length * 2)
Merge1(A, TmpA, i, i + length, i + 2 * length - 1);
if (i + length < N)
Merge1(A, TmpA, i, i + length, N - 1);
else
for (j = i; j < N; j++) TmpA[j] = A[j];
}
void MergeSort(int A[], int N, int target[])
{
int *TmpA = (int*)malloc(sizeof(int) * N);
int i, length = 1;
while (length < N) {
MergePass(A, TmpA, N, length);
length *= 2;
if (IsSame(TmpA, N, target)) {
printf("Merge Sort\n");
MergePass(TmpA, A, N, length);
length *= 2;
free(TmpA);
for (i = 0; i < N; i++)
if (i) printf(" %d", A[i]);
else printf("%d", A[i]);
break;
}
MergePass(TmpA, A, N, length);
length *= 2;
if (IsSame(A, N, target)) {
printf("Merge Sort\n");
MergePass(A, TmpA, N, length);
length *= 2;
free(TmpA);
for (i = 0; i < N; i++)
if (i) printf(" %d", A[i]);
else printf("%d", A[i]);
break;
}
}
}
int main()
{
int i, N, A[100], target[100];
scanf("%d", &N);
for (i = 0; i < N; i++) scanf("%d", &A[i]);
for (i = 0; i < N; i++) scanf("%d", &target[i]);
if (InserstionSort(A, N, target)) ;
else MergeSort(A, N, target);
return 0;
}