# include <bits/stdc++.h>
using namespace std;
int M, N;
vector<int> A(1001);
// 使用DFS遍历树,每次都只判断当前结点u和它的左后孩子符不符合堆的要求
void DFS(int u, int &flag){
if(u == 1){
// 初始化第一次
if(N == 2) {
if(A[u] >= A[u*2]) flag = 2;
else
if(A[u] < A[u*2]) flag = 1;
}
else {
if(A[u] >= A[u*2] && A[u] >= A[u*2 + 1]) flag = 2;
else
if(A[u] < A[u*2] && A[u] < A[u*2 + 1]) flag = 1;
else flag = 0;
}
}
else {
//然后后面每一次的判断都根据前一次的flag来判断,如果上一次的flag和这一次的要求不一致,说明not heap
if(u > N) return;
if(u*2 <= N){
// 不是叶子结点
if(u*2 + 1 <= N){
// 有左右孩子(有右孩子,那必然有左孩子)
if(flag == 2 && A[u] >= A[u*2] && A[u] >= A[u*2 + 1]) flag = 2; // 当前结点仍符合大根堆
else
if(flag == 1 && A[u] < A[u*2] && A[u] < A[u*2 + 1]) flag = 1; // 当前结点仍符合小根堆
else flag = 0; // 当前结点既不是大根堆也不是小根堆,那就不是堆
} else {
// 只有左孩子
if(flag == 2 && A[u] >= A[u*2]) flag = 2;
else
if(flag == 1 && A[u] < A[u*2]) flag = 1;
else flag = 0;
}
} else {
// 是叶子结点
return;
}
}
if(flag == 0) return; // 当前结点表明该序列不是堆,直接返回。
DFS(u*2 , flag); // 向左子树递归
DFS(u*2 + 1, flag); // 向右子树递归
}
int cnt;
void postTraverse(int root){
// 后序遍历
if(root > N) return;
postTraverse(root*2);
postTraverse(root*2 + 1);
cout << A[root] << (cnt++ == N-1 ? "\n" : " ");
}
int main() {
cin >> M >> N;
for(int i = 0;i < M;++i){
for(int j = 1;j <= N;++j)
cin >> A[j];
int flag;
DFS(1, flag);
if(flag == 2){
cout << "Max Heap" << endl;
} else
if(flag == 1){
cout << "Min Heap" << endl;
} else
if(flag == 0) {
cout << "Not Heap" << endl;
}
cnt = 0;
postTraverse(1);
}
return 0;
}
[PAT Class A Heap/Tree Traversal C++] 1147 Heaps (30 points)
Guess you like
Origin blog.csdn.net/MYMarcoreus/article/details/114240333
Ranking