题目链接
题目分析
1、给出一段序列,判断是插入排序还是堆排序的中间结果,并输出下一步
2、题目保证结果唯一
3、初始队列不进行比对
解题思路
模拟每种排序的过程,在每一步操作后进行比对
1、判断时先走堆排序(更快),这样节省时间
2、插入排序中实际每一步的操作可以使用现成的sort()算法
时间复杂度:每走一步次都比对一遍? 结点上限100,双重循环到10000数量级?
AC程序(C++)
/**********************************
*@ID: 3stone
*@ACM: PAT.A1098 Insertion or Heap Sort
*@Time: 18/8/14
*@IDE: VSCode 2018 + clang++
***********************************/
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn = 110;
int org_1[maxn], org_2[maxn]; //原始序列(保存两份,用于两种排序)
int test[maxn]; //待检查序列
int N;
//判断两序列是够相同
bool check(int flag) {
if(flag == 1){ //insertion_sort
for(int i = 0; i < N; i++)
if(org_1[i] != test[i])
return false;
return true;
} else { //heap_sort(需要从1号位开始存储)
for(int i = N; i > 0; i--) //逆序匹配,因为heap_sort的sorted region在后边
if(org_2[i] != test[i - 1])
return false;
return true;
}
}
int find_insert_key(int st, int value) {
for(int i = st; i >= 0; i--)
if(org_1[i] <= value){
return i + 1; //返回要插入的位置下标
} else {
continue;
}
return 0; //插入到队首
}
void insert_move(int st, int tar) {
if(st == tar) return;
int temp = org_1[tar];
for(int i = tar; i > st; i--){
org_1[i] = org_1[i - 1];
}
org_1[st] = temp;
}
void insertion_sort() {
bool flag = false;
for(int i = 1; i < N; i++) { //从第2个元素开始 (同时保证初始序列不参与比较)
//从下标key到下标i-1 全部向后移动一个单位
int key = find_insert_key(i - 1, org_1[i]);
insert_move(key, i);
//当然也可以不用真的模拟每一步,排序可以由sort()实现
//sort(org_1, org_1 + i + 1); //注意sort()的规则是[)
//对比(全值)
if(flag) break; //放在此处原因:多插入一步之后退出
if(check(1)){
flag = true;
}
}
if(flag){ //匹配成功
//输出下一步队列
printf("Insertion Sort\n");
for(int i = 0; i < N - 1; i++)
printf("%d ", org_1[i]);
printf("%d\n", org_1[N - 1]);
}
}
void downAdjust(int low, int heigh) {
int i = low, j = i * 2;
while(j <= heigh) {
if(j + 1 <= heigh && org_2[j] < org_2[j + 1])
j++;
if(org_2[i] < org_2[j]){
swap(org_2[i], org_2[j]);
i = j;
j = i * 2;
} else {
break;
}
}//while
}
void create_heap() {
for(int i = N / 2; i > 0; i--) {
downAdjust(i, N);
}
}
bool heap_sort() {
create_heap(); //建堆
bool flag = false;
for(int i = N; i > 1; i--) {
swap(org_2[i], org_2[1]);
downAdjust(1, i - 1);
if(flag) break;
if(check(2)) {
flag = true;
}
}
if(flag){
printf("Heap Sort\n");
for(int i = 1; i < N; i++)
printf("%d ", org_2[i]);
printf("%d\n", org_2[N]);
return true;
}
return false;
}
int main() {
while(scanf("%d", &N) != EOF) {
//input
for(int i = 0; i < N; i++) {
scanf("%d", &org_1[i]);
org_2[i + 1] = org_1[i]; //堆(完全二叉树)需要从1号位开始存储
}
for(int i = 0; i < N; i++) {
scanf("%d", &test[i]);
}
if(!heap_sort()){ //堆排序检测失败再检查插入排序
insertion_sort();
}
}
return 0;
}