【PAT甲级题解记录】1155 Heap Paths (30 分)
前言
Problem:1155 Heap Paths (30 分)
Tags:树的遍历 DFS
Difficulty:剧情模式
想流点汗想流点血死而无憾Address:1155 Heap Paths (30 分)
问题描述
给一棵完全二叉树,求其是否为堆,要求输出大根堆还是小根堆,并且输出每一条自上而下的分支路径。
解题思路
-
对于路径的输出,利用dfs(其实就是二叉树的NRL遍历,和先序遍历差不多,先序遍历是NLR)配合动态维护vector就可以完成。
-
至于堆性质的判定,我们可以直接判断heap[0]和heap[1]的大小顺序,然后以此顺序为参照,在dfs里判断path是否按照该顺序排序。
参考代码
/*
* @Author: Retr0.Wu
* @Date: 2022-02-24 16:11:22
* @Last Modified by: Retr0.Wu
* @Last Modified time: 2022-02-24 16:11:22
*/
#include <bits/stdc++.h>
using namespace std;
map<int, int> tree;
vector<int> order;
void outputs()
{
for (int i = 0; i < order.size(); i++)
{
if (i > 0)
cout << " ";
cout << order[i];
}
cout << endl;
}
int dfs(int root, int type, int isput)
{
// cout<<tree[root]<<endl;
order.push_back(tree[root]);
int ans = 1;
if (tree.count(root * 2 + 2))
{
if (type * (tree[root] - tree[root * 2 + 2]) < 0)
{
ans = 0;
}
if (!dfs(root * 2 + 2, type, isput))
{
ans = 0;
}
}
if (tree.count(root * 2 + 1))
{
if (type * (tree[root] - tree[root * 2 + 1]) < 0)
{
ans = 0;
}
if (!dfs(root * 2 + 1, type, isput))
{
ans = 0;
}
}
if (!tree.count(root * 2 + 2) && !tree.count(root * 2 + 1) && isput)
{
outputs();
}
order.pop_back();
return ans;
}
int main()
{
int N;
cin >> N;
for (int i = 0; i < N; i++)
{
cin >> tree[i];
}
if (dfs(0, 1, 0))
{
dfs(0, 1, 1);
cout << "Max Heap" << endl;
}
else if (dfs(0, -1, 0))
{
dfs(0, 1, 1);
cout << "Min Heap" << endl;
}
else
{
dfs(0, 1, 1);
cout << "Not Heap" << endl;
}
}