PAT-ADVANCED1098/Data Structures and Algorithms7-14——Insertion or Heap Sort

我的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++解题报告:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值