1098 Insertion or Heap Sort (25 分)
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.
Heap sort divides its input into a sorted and an unsorted region, and it iteratively shrinks the unsorted region by extracting the largest element and moving that to the sorted region. it involves the use of a heap data structure rather than a linear-time search to find the maximum.
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 "Heap 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 resulting 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 6 0 6 4 5 1 0 3 2 7 8 9
Sample Output 2:
Heap Sort 5 4 3 1 0 2 6 7 8 9
======================================
题意:
给定原始序列 和 排序序列的中间过程,请判断是 堆排 还是 直接插入排序 ?并输出下一趟排序的结果。
解题:
需要先了解堆排的过程及实现。
直接插入排序特点:前面有序递增,后面未排序的部分和原始序列相同。否则就是堆排。
下一步是:对前面的有序部分 + 将第一个不递增的数 进行一次Sort。
堆排特点:从后往前有序递减,前面未排序的部分第一个元素是未排序中最大的(题目给定大顶堆)。
下一步:将第一个不递减的数(假设下标是 i )与 第一个元素交换,并且调整 1至 i - 1成大顶堆。
======================================
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> a, b;
void downAdjust(int low, int high){//调整1-i-1为大顶堆
int i = low, j = 2 * low;
while(j <= high){
if(j < high && b[j] < b[j + 1])
j++;
if(b[i] < b[j]){
swap(b[i], b[j]);
i = j;
j = 2 * j;
}
else
break;
}
}
int main(){
int n, p = 2;
scanf("%d", &n);
a.resize(n + 1), b.resize(n + 1);
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for(int i = 1; i <= n; i++)
scanf("%d", &b[i]);
while(p <= n && b[p - 1] <= b[p]) p++;//寻找第一个不递增的位置
int index = p;
while(p <= n && a[p] == b[p]) p++;//未排序部分 是否 和原始序列一致
if(p == n + 1){//p到达n+1,说明一致,是直接插入排序。否则是堆排
printf("Insertion Sort\n");
sort(b.begin() + 1, b.begin() + index + 1);//下一趟
printf("%d", b[1]);//输出下一趟结果
for(int i = 2; i <= n; i++)
printf(" %d", b[i]);
} else{//否则是堆排
printf("Heap Sort\n");
p = n;
while(p >= 2 && b[p] >= b[p - 1]) p--;//寻找第一个非递减的数
swap(b[1], b[p]);
downAdjust(1, p - 1);//调整1至P-1成大顶堆
printf("%d", b[1]);
for(int i = 2; i <= n; i++)
printf(" %d", b[i]);
}
return 0;
}