PAT 乙级 1035 插入与归并 v0.6.1
1. 题目简述及在线测试位置
1.1 根据N趟排序后的元素序列(N未知) 推断出使用的排序算法,随后打印N+1趟排序后的序列。题目中使用的排序算法是插入排序或归并排序
1.2 在线测试位置:PAT 1035 插入与归并
2. 基本思路
之前总结过,解题思路请参考Insert or Merge,正确实现插入和归并的非递归算法就可以AC
3. 完整AC代码
#include <iostream>
using namespace std;
#define MAX 100
void Merge_Pass(int a[], int tmp[], int N, int Length);
void Merge(int a[], int b[], int Left, int Right, int RightEnd);
void MergeSortAndJudge(int a[], int b[], int N);
void InsertSortAndJudge(int a[],int b[], int N);
bool Judge(int a[], int b[], int N);
bool flag = false; //
int main()
{
int Origin[MAX], Sorting[MAX],Bak[MAX];
int N;
cin >> N;
for (int i = 0; i < N; i++)
{
cin >> Origin[i];
Bak[i]= Origin[i];
}
for (int i = 0; i < N; i++)
cin >> Sorting[i];
MergeSortAndJudge(Origin,Sorting, N);
if (flag)
return 0;
for (int i = 0; i < N; i++)
Origin[i] = Bak[i];
InsertSortAndJudge(Origin, Sorting, N);
return 0;
}
void MergeSortAndJudge(int a[], int b[], int N)
{
int Length = 1;//归并子序列初始长度为1
int tmp[MAX];
while (Length < N)
{
Merge_Pass(a, tmp, N, Length);
Length *= 2;
if (flag)
{
cout << tmp[0];
for (int i = 1; i < N; i++)
cout<<" " << tmp[i];
return;
}
if (Judge(tmp, b, N))
{
flag = true;
cout << "Merge Sort" << endl;
}
Merge_Pass(tmp, a, N, Length);
Length *= 2;
if (flag)
{
cout << a[0];
for (int i = 1; i < N; i++)
cout << " " << a[i];
return;
}
if (Judge(a, b, N))
{
flag = true;
cout << "Merge Sort" << endl;
}
}
return;
}
//两两归并相邻有序子列
//tmp是归并排序算法中创建的数组,大小为N,同数组a
//Length是有序子列的长度,初始值为1
void Merge_Pass(int a[], int tmp[], int N, int Length)
{
int i, j;
//N - 2*Length 是为了确保每次Merge,一定有两个有序子列
for (i = 0; i <= N - 2 * Length; i = i + 2 * Length) //Hard!!
Merge(a, tmp, i, i + Length, i + 2 * Length - 1);
if (i + Length < N) //归并最后2个子列
Merge(a, tmp, i, i + Length, N - 1);
else //只有一个子列了
for (j = i; j < N; j++)
tmp[j] = a[j];
}
//将数组a分为两部分[Left,Right-1],[Right,RightEnd]
//按从小到大的规则,对这两部分进行排序,将结果存放到数组b
void Merge(int a[], int b[], int Left, int Right, int RightEnd)
{
int ArrayNumber= RightEnd-Left+1;//数组a的元素个数 //数组a 数组b元素个数相同
int LeftEnd = Right - 1; //将数组a分为两部分
int index=Left;//数组b的初始索引值 = 数组a的首元素索引值
while (Left <= LeftEnd && Right <= RightEnd)
{
if (a[Left] <= a[Right])
b[index++] = a[Left++];
else
b[index++] = a[Right++];
}
while (Left <= LeftEnd)
b[index++] = a[Left++];
while (Right <= RightEnd)
b[index++] = a[Right++];
return;
}
void InsertSortAndJudge(int a[], int b[], int N)
{
int i, j,tmp;
for (i = 1; i < N; i++)
{
tmp = a[i];
for (j = i; j > 0 && a[j - 1] > tmp; j--) //从后向前
a[j] = a[j - 1];
a[j] = tmp;
if (flag)
{
int k = 0; cout << a[k];
for (k = 1; k < N; k++)
cout << " " << a[k];
return;
}
if (Judge(a, b, N))
{
flag = true;
cout << "Insertion Sort" << endl;
}
}
return;
}
bool Judge(int a[], int b[], int N)
{
for (int i = 0; i < N; i++)
if (a[i] != b[i])
return false;
return true;
}