题目链接:https://pintia.cn/problem-sets/994805342720868352/problems/1071785408849047552
题意:给出一颗完全二叉树,打印出从根节点到所有叶节点的路径,打印顺序先右后左,即先序遍历的镜像。然后判断该树是大顶堆、小顶堆或者不是堆~
分析:1.深搜打印出所有路径(从右往左,即先序的镜像),通过push和pop回溯,维护路径
2…判断是否为堆:从第二个节点开始遍历,如果比父节点小,就不是小顶堆,如果比父节点大,就不是大顶堆~
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e3+10;
int n;
int vis[maxn];
int a[maxn];
int st[maxn]; //栈,用于输出路径
int k;
int cnt1; //判断是否是大顶堆
int cnt2; // 判断是否是小顶堆
void print(int k)
{
for(int i=0; i<k; i++)
{
if(i==0)
printf("%d",a[st[i]]);
else
printf(" %d",a[st[i]]);
}
for(int i=1; i<k; i++)
{
if(a[st[i]]>=a[st[i-1]]) //比双亲结点大,是小顶堆
cnt2 = 1;
}
for(int i=1; i<k; i++)
{
if(a[st[i]]<=a[st[i-1]]) //比双亲结点小,是大顶堆
cnt1 = 1;
}
printf("\n");
}
void dfs(int s)
{
vis[s] = 1;
st[k++] = s;
if(s*2>n)
{
print(k);
}
if(s*2+1<=n) //向右子树递归搜索
{
dfs(s*2+1);
k--;
}
if(s*2<=n) //向左子树递归搜索
{
dfs(s*2);
k--;
}
}
int main()
{
scanf("%d",&n);
int i;
for(i=1; i<=n; i++)
{
scanf("%d",&a[i]);
}
k = 0;
cnt1 = 0;
cnt2 = 0;
dfs(1);
if(cnt1&&cnt2)
printf("Not Heap");
else if(cnt1)
printf("Max Heap\n");
else if(cnt2)
printf("Min Heap\n");
return 0;
}