题目大意:
判断一个完全二叉树是最大堆还是最小堆还是不是堆,然后输出后序遍历的结果。
解题思路:
根据最大最小堆的定义依次判断父节点和子节点的关系并记录,如果记录出现冲突说明不是一个堆,否则就输出记录的结果,最后输出后序遍历。
代码如下:
#include<iostream>
#include<cstdio>
#include<fstream>
#include<set>
#include<cmath>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<iomanip>
#include<cstdlib>
#include<list>
#include<queue>
#include<stack>
#include<algorithm>
#define inf 0x3f3f3f3f
#define MOD 1000000007
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define meminf(a) memset(a,inf,sizeof(a))
//vector ::iterator it;
//set<int>::iterator iter;
//fill(function+begin.,function+length,key);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
int heap[2100],n,m,num;
void postorder(int root)//输出后序遍历
{
if(root>m)return;
postorder(root*2);
postorder(root*2+1);
printf("%d",heap[root]);
num++;
if(num<m)printf(" ");
}
int main()
{
// std::ios::sync_with_stdio(false);
// cin.tie(0);
// freopen("test.txt","r",stdin);
// freopen("output.txt","w",stdout);
scanf("%d %d",&n,&m);
while(n--)
{
num=0;
for(int i=1;i<=m;i++)scanf("%d",&heap[i]);
bool ma=false,mi=false,no=false;
for(int i=1;i<=m/2;i++)
{
int num1,num2;
if(i*2+1<=m)//如果有右儿子
{
if(heap[i]>=heap[2*i]&&heap[i]>=heap[2*i+1])ma=true;
else if(heap[i]<=heap[2*i]&&heap[i]<=heap[2*i+1])mi=true;
else no=true;
}
else
{
if(heap[i]>=heap[2*i])ma=true;
else if(heap[i]<=heap[2*i])mi=true;
}
if(no)break;
if(ma&&mi)
{
no=true;
break;
}
}
if(no||m==0)printf("Not Heap\n");
else if(ma)printf("Max Heap\n");
else printf("Min Heap\n");
postorder(1);
printf("\n");
}
return 0;
}