我的PAT-ADVANCED代码仓:https://github.com/617076674/PAT-ADVANCED
我的Data Structures and Algorithms代码仓:https://github.com/617076674/Data-Structures-and-Algorithms
原题链接:
PAT-ADVANCED1098:https://pintia.cn/problem-sets/994805342720868352/problems/994805368847187968
Data Structures and Algorithms7-14:https://pintia.cn/problem-sets/16/problems/676
题目描述:
PAT-ADVANCED1098、Data Structures and Algorithms7-14:
题目翻译:
1098 插入排序与堆排序
根据维基百科的定义如下:
插入排序迭代,每次重复消耗一个输入元素,并生成排序的输出列表。 每次迭代,插入排序都会从输入数据中删除一个元素,在排序列表中找到它所属的位置,然后将其插入到那里。 它重复直到没有输入元素。
堆排序将其输入划分为排序和未排序区域,并通过提取最大元素并将其移动到排序区域来迭代缩小未排序区域。 它涉及使用堆数据结构而不是线性时间搜索来找到最大值。
现在给出初始的整数序列,以及一些序列,这是一些排序方法的几次迭代的结果,你能告诉我们正在使用哪种排序方法吗?
输入格式:
每个输入文件包含一个测试用例。在每个测试用例中,第一行给出一个正整数N(<= 100)。接下来的一行给出N个整数,作为初始序列。最后一行给出N个整数,代表某排序算法的中间序列。假设目标序列是升序。 一行中的所有数字都由一个空格分隔。
输出格式:
对每个测试用例,在第一行输出“Insertion Sort”或“Heap Sort”来说明产生该中间序列所使用的排序算法。然后再运行此算法一次迭代,并在第二行输出结果序列。 保证每个测试用例的答案都是唯一的。 一行中的所有数字必须用空格分隔,并且行尾必须没有多余的空格。
输入样例1:
10
3 1 2 8 7 5 9 4 6 0
1 2 3 7 8 5 9 4 6 0
输出样例1:
Insertion Sort
1 2 3 5 7 8 9 4 6 0
输入样例2:
10
3 1 2 8 7 5 9 4 6 0
6 4 5 1 0 3 2 7 8 9
输出样例2:
Heap Sort
5 4 3 1 0 2 6 7 8 9
知识点:插入排序、堆排序
思路:先判断是否是插入排序,再分别进行下一步操作
判断是否是插入排序的方法和PAT-BASIC1035——插入与归并相同。
(1)如果是插入排序,寻找到已经排好序的前k - 1个元素,对第k个元素进行插入排序。
(2)如果是堆排序,寻找到位置k,使得k + 1之后的元素已经排好序。对[0, k]范围内的元素,先交换0和k位置的值,再对[0, k - 1]范围内的堆顶元素,即0位置的元素进下沉操作。
如果是插入排序,时间复杂度是O(N)。而如果是堆排序,由于我们需要一个双重循环来寻找位置k,因此时间复杂度是O(N ^ 2)。空间复杂度均是O(1)。
C++代码:
#include<iostream>
using namespace std;
int N, index = -1;
bool isInsertionSort(int input1[], int input2[]);
void nextInsertionSort(int* input);
void nextHeapSort(int* input);
void print(int* input);
int main() {
scanf("%d", &N);
int input1[N];
for(int i = 0; i < N; i++) {
scanf("%d", &input1[i]);
}
int input2[N];
for(int i = 0; i < N; i++) {
scanf("%d", &input2[i]);
}
if(isInsertionSort(input1, input2)) {
printf("Insertion Sort\n");
nextInsertionSort(input2);
} else {
printf("Heap Sort\n");
nextHeapSort(input2);
}
print(input2);
return 0;
}
bool isInsertionSort(int input1[], int input2[]) {
for(int i = 0; i < N; i++) {
if(input2[i + 1] < input2[i]) {
index = i + 1;
break;
}
}
for(int i = index; i < N; i++) {
if(input1[i] != input2[i]) {
return false;
}
}
return true;
}
void nextInsertionSort(int* input) {
int temp = input[index];
int j = index - 1;
for(; input[j] > temp && j >= 0; j--) {
input[j + 1] = input[j];
}
input[j + 1] = temp;
}
void nextHeapSort(int* input) {
int range;
for(int i = 1; i < N; i++){
if(input[i] > input[0]){
range = i - 1;
break;
}
}
swap(input[0], input[range]);
int i = 0, j = 2 * i + 1;
while(j <= range - 1) {
if(j + 1 <= range - 1 && input[j + 1] > input[j]) {
j++;
}
if(input[j] > input[i]) {
swap(input[i], input[j]);
i = j;
j = 2 * i + 1;
} else {
break;
}
}
}
void print(int* input) {
for(int i = 0; i < N; i++) {
printf("%d", input[i]);
if(i != N - 1) {
printf(" ");
} else {
printf("\n");
}
}
}
C++解题报告: