1098 Insertion or Heap Sort(25分)

题目翻译:

首先给定一个排序之前的序列,然后再给出一个进行到排序完成之前的一个“中间序列”,判断使用的是插入排序还是堆排序,并给出下一步的排序结果。

题解思路:

按照下面的思路展开:

  1. 首先求出第二个序列中从左向右第一个无序元素位置;
  2. 接着和a对比接下来的(因为如果是插入排序后边的是一样的),若一致,则是插入排序,只需要从无序位置和前面的比对找到合适位置插入即可;
  3. 如果不一致,证明是堆排序,要先从后向前遍历,找到首个小于堆首的元素位置(因为按题意堆排序是将最大值放到后面作为已排序区域),然后先对未排序区域执行以下操作:
  • 将堆首元素(未排序区域的最大值)和未排序区域的最后一个元素(注意不是指最小值)交换位置;
  • 然后重新平衡二叉树,使得二叉树重新为堆二叉树(根结点大于等于左右孩子结点)。

也可以参考1097

代码:

#include<bits/stdc++.h>
using namespace std;
int a[101], b[101];
void Next_step(int curnode, int len)
{
	int k = curnode;
	if (curnode * 2 <= len && b[curnode] < b[2 * curnode]) k = 2* curnode;
	if (curnode * 2 + 1 <= len && b[k] < b[2 * curnode + 1]) k = 2* curnode + 1;
	if (k != curnode)//左右结点大于目前结点
	{
		swap(b[k], b[curnode]);
		Next_step(k, len);   
	}
}
int main()
{
	int N;cin >> N;
	for (int i = 1;i <= N;i++)cin >> a[i];
	for (int i = 1;i <= N;i++)cin >> b[i];
	int pos1;//b数组中第一个无序的位置
	for (int i = 2;i <= N;i++)
		if (b[i] > b[i + 1])
		{
			pos1 = i+1;
			break;
		}
	int k = pos1;
	while (b[k] == a[k] && k <= N)
		k++;
	if (k == N + 1)
	{
		cout << "Insertion Sort" << endl;
		while (pos1 >= 1 && b[pos1] < b[pos1 - 1]) swap(b[pos1 - 1], b[pos1]), pos1--;//从无序位置进行下次插入排序
	}
	else
	{
		cout << "Heap Sort" << endl;
		k = N;
		while (b[k] >= b[1]) k--;
		swap(b[1], b[k]);//将堆顶元素和从后向前第一个无序位置(未排序区域的最后一个位置,先将其换到根结点)交换
		Next_step(1, k - 1);//使二叉树重新“有序”(根节点大于等于左右孩子结点的值)
	}
	cout << b[1];
	for (int i = 2;i <= N;i++)
		cout << " " << b[i];
}

坑点:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值