堆(c++)数据结构

13 篇文章 2 订阅
12 篇文章 4 订阅

判断是否为堆

题目描述
请判断输入的整数序列是否为堆。
如果为最大堆,请输出“max ”以及整理后的最小堆,整数序列数字之间有空格,最后无空格。
如果为最小堆,请输出“min ” 以及整理后的最大堆,整数序列数字之间有空格,最后无空格。
如果不为堆,请输出整理后的最大堆,整数序列数字之间有空格,最后无空格。
如果既是最大堆也是最小堆,请只输出“max min ”

Input Format
先输入整数序列个数n 0<n<1000
然后输入n个整数序列,整数取值范围【-100000,100000】
Output Format
最大堆或最小堆序列
Example
Input
10
-8 8 -9 10 -2 1 -6 -9 7 2
Output
10 8 1 7 2 -9 -6 -9 -8 -2
Input
10
10 8 1 7 2 -9 -6 -9 -8 -2
Output
max -9 -9 -6 -8 -2 1 10 7 8 2
Input
10
-9 -9 -6 -8 -2 1 10 7 8 2
Output
min 10 8 1 7 2 -9 -6 -9 -8 -2
Input
3
1 1 1
Output
max min

注意:序列最后无空格,max和min后面均有空格。
如案例,定义以下实现约束:两个相等子节点情况下,整理过程中,父节点下沉时,选择右沉。
10
10 8 1 7 2 -9 -6 -9 -8 -2
两个相等子节点情况下,整理过程中,父节点下沉时,选择右沉。

具体代码:

#include<iostream>
using namespace std;
int flag = 0; 
void IsHeap(int num[], int n) {
	bool isMax = true, isMin = true;//初始默认为堆 
	int lChild, rChild;
	for (int i = 1; i <= n; ++i) 
	{
		lChild = i * 2;
		rChild = i * 2 + 1;
		if (rChild <= n) 
		{
			if (num[i] == num[lChild] && num[i] == num[rChild])continue;//结点与孩子相等,可以是最大堆也可以是最小堆。 
			else if (num[i] <= num[lChild] && num[i] <= num[rChild])//结点的左右孩子都不比它小,故不是最大堆。 
				isMax = false;
			else if (num[i] >= num[lChild] && num[i] >= num[rChild])//结点的左右孩子都不比它大,故不是最小堆。 
				isMin = false;
			else
			{
				isMax = isMin = false;
				break;
			}
		}
		else if (lChild <= n) 
		{
			if (num[i] == num[lChild])continue;
			else if (num[i] < num[lChild])
				isMax = false;
			else if (num[i] > num[lChild])
				isMin = false;
			else 
			{
				isMax = isMin = false;
				break;
			}
		}
	}
	//四种结果 
	if (isMax == true) 
	{
		if (isMin == false)flag = 1;
		if (isMin == true)flag = 3;
	}
	else 
	{
		if (isMin == true)flag = 2;
		if (isMin == false)flag = 4;
	}
}
void BuildMaxHeap(int num[], int n) //生成最大堆 
{
	for (int i = n / 2; i >= 1; --i) 
	{
		int t = num[i];//结点 
		int c = i * 2;//左孩子 
		while (c <= n) 
		{
			if (c < n && num[c] <= num[c + 1])
				c++;
			if (t < num[c]) //结点小于左孩子 
			{
				num[c / 2] = num[c];//将左孩子的值赋给结点 
				c *= 2;//出while循环 
			}
			else break;//出while循环 
		}
		num[c / 2] = t;//将原结点的值赋给左孩子 
	}
}

void BuildMinHeap(int num[], int n) //生成最小堆 
{
	for (int i = n / 2; i >= 1; --i) 
	{
		int t = num[i];
		int c = i * 2;
		while (c <= n) 
		{
			if (c < n && num[c] >= num[c + 1])
				c++;
			if (t > num[c]) 
			{
				num[c / 2] = num[c];
				c *= 2;
			}
			else break;
		}
		num[c / 2] = t;
	}
}
void BuildHeap(int num[], int n) 
{

	if (flag == 1) 
	{
		cout << "max ";
		BuildMinHeap(num, n);
	}
	if (flag == 2) 
	{
		cout << "min ";
		BuildMaxHeap(num, n);
	}
	if (flag == 3) 
	{
		cout << "max min" << endl;
		return;
	}
	if (flag == 4) 
	{
		BuildMaxHeap(num, n);
	}
	for (int i = 1; i <= n; ++i) 
	{
		if (i == n)cout << num[i];
		else cout << num[i] << " ";
	}
}
int main() {
	int n, num1[1001];
	cin >> n;
	for (int i = 1; i <= n; ++i)
		cin >> num1[i];
	IsHeap(num1, n);
	BuildHeap(num1, n);
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值