PAT甲级——A1155 HeapPaths【30】

时间:2021-09-24 05:22:16

In computer science, a heap is a specialized tree-based data structure that satisfies the heap property: if P is a parent node of C, then the key (the value) of P is either greater than or equal to (in a max heap) or less than or equal to (in a min heap) the key of C. A common implementation of a heap is the binary heap, in which the tree is a complete binary tree. (Quoted from Wikipedia at https://en.wikipedia.org/wiki/Heap_(data_structure))

One thing for sure is that all the keys along any path from the root to a leaf in a max/min heap must be in non-increasing/non-decreasing order.

Your job is to check every path in a given complete binary tree, in order to tell if it is a heap or not.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (1), the number of keys in the tree. Then the next line contains N distinct integer keys (all in the range of int), which gives the level order traversal sequence of a complete binary tree.

Output Specification:

For each given tree, first print all the paths from the root to the leaves. Each path occupies a line, with all the numbers separated by a space, and no extra space at the beginning or the end of the line. The paths must be printed in the following order: for each node in the tree, all the paths in its right subtree must be printed before those in its left subtree.

Finally print in a line Max Heap if it is a max heap, or Min Heap for a min heap, or Not Heap if it is not a heap at all.

Sample Input 1:

8
98 72 86 60 65 12 23 50

Sample Output 1:

98 86 23
98 86 12
98 72 65
98 72 60 50
Max Heap

Sample Input 2:

8
8 38 25 58 52 82 70 60

Sample Output 2:

8 25 70
8 25 82
8 38 52
8 38 58 60
Min Heap

Sample Input 3:

8
10 28 15 12 34 9 8 56

Sample Output 3:

10 15 8
10 15 9
10 28 34
10 28 12 56
Not Heap

Solution:
  这道题很简单,和前面的一道题类似
  抓住两个重要条件:
    一个是大根堆,小根堆的特点
    一个是完全二叉树的性质
  然后通过层序遍历序列重构二叉树
  通过序列中第一个数与第二个数的大小比较就可以知道是大根堆还是小根堆【注意,一般不要相信题目中所谓的等于,因为PAT中的节点值就从来没有等于过】
  通过判断节点与其孩子节点的值的大小可知是否满足Heap Tree的性质
  最后使用DFS来输出路径,记得先右再左
  
 1 #include <iostream>
 2 #include <vector>
 3 #include <queue>
 4 #include <algorithm>
 5 using namespace std;
 6 struct Node
 7 {
 8     int val;
 9     Node *l, *r;
10     Node(int a = 0) :val(a), l(nullptr), r(nullptr) {}
11 };
12 int n;
13 vector<int>level;
14 Node *creatTree(int index)//重构二叉树
15 {
16     Node *root = new Node(level[index  ]);
17     queue<Node*>q;
18     q.push(root);
19     while (!q.empty() && index<n)
20     {
21         Node *p = q.front();
22         q.pop();
23         p->l = new Node(level[index  ]);
24         q.push(p->l);
25         if (index >= n)break;
26         p->r = new Node(level[index  ]);
27         q.push(p->r);
28     }
29     return root;
30 }
31 vector<int>res;
32 void DFS(Node *root, bool isMaxHeap,bool &isHeap)
33 {
34     if (root == nullptr)
35         return;
36     res.push_back(root->val);
37     if (isMaxHeap)//大根堆判断
38     {
39         if ((root->l && root->l->val > root->val) || (root->r && root->r->val > root->val))
40             isHeap = false;
41     }
42     else//小根堆判断
43     {
44         if ((root->l && root->l->val < root->val) || (root->r && root->r->val < root->val))
45             isHeap = false;
46     }
47     if (root->l == nullptr && root->r == nullptr)//输出路径
48     {
49         for (int i = 0; i < res.size();   i)
50             cout << (i == 0 ? "" : " ") << res[i];
51         cout << endl;
52     }
53     DFS(root->r, isMaxHeap, isHeap);//记得先右再左
54     DFS(root->l, isMaxHeap, isHeap);
55     res.pop_back();
56 }
57 int main()
58 {
59     cin >> n;
60     level.resize(n);
61     for (int i = 0; i < n;   i)
62         cin >> level[i];
63     Node* root = creatTree(0);
64     bool isHeap = true;
65     bool isMaxHeap = level[0] >= level[1] ? 1 : 0;
66     DFS(root, isMaxHeap, isHeap);
67     if (isHeap && isMaxHeap)
68         cout << "Max Heap" << endl;
69     else if (isHeap && !isMaxHeap)
70         cout << "Min Heap" << endl;
71     else
72         cout << "Not Heap" << endl;
73     return 0;
74 }

 

原谅孩子不会静态重构二叉树吧 :), 静态重构【就是根据序列数位置得到整个数树的形状】是我的硬伤,相信不久的明天我就学会了 ^_^
这里借用一下别人静态重构的代码吧
 1 #include <iostream>
 2 #include <vector>
 3 using namespace std;
 4 vector<int> v;
 5 int a[1009], n, isMin = 1, isMax = 1;
 6 void dfs(int index) {
 7     if (index * 2 > n && index * 2   1 > n) {
 8         if (index <= n) {
 9             for (int i = 0; i < v.size(); i  )
10                 printf("%d%s", v[i], i != v.size() - 1 ? " " : "n");
11         }
12     }
13     else {
14         v.push_back(a[index * 2   1]);
15         dfs(index * 2   1);
16         v.pop_back();
17         v.push_back(a[index * 2]);
18         dfs(index * 2);
19         v.pop_back();
20     }
21 }
22 int main() {
23     cin >> n;
24     for (int i = 1; i <= n; i  )
25         scanf("%d", &a[i]);
26     v.push_back(a[1]);
27     dfs(1);
28     for (int i = 2; i <= n; i  ) {
29         if (a[i / 2] > a[i]) isMin = 0;
30         if (a[i / 2] < a[i]) isMax = 0;
31     }
32     if (isMin == 1)
33         printf("Min Heap");
34     else
35         printf("%s", isMax == 1 ? "Max Heap" : "Not Heap");
36     return 0;
37 }