目录
1,题目描述
Sample Input:
3 8
98 72 86 60 65 12 23 50
8 38 25 58 52 82 70 60
10 28 15 12 34 9 8 56
Sample Output:
Max Heap
50 60 65 72 12 23 86 98
Min Heap
60 58 52 38 82 70 25 8
Not Heap
56 12 34 28 9 8 15 10
题目大意
给出一个完全二叉树(这条件太棒了!),判断这棵树是大根堆还是小根堆,或者都不是,并且输出这棵树的后序遍历。
2,思路
完全二叉树一个最大的特点就是,当一个树存放在以1开始的数组中时,对于每个位置index来说,2*index和2*index+1分别是其左右两个孩子节点!
那不就好起来了嘛o(* ̄︶ ̄*)o
DFS解决所有烦恼
注意,这里我用set集合记录是否为大/小根堆,当父节点大于子节点时,插入1,否则插入0;最后判断size是否为1,不唯一说明不是堆,否则判断元素是1还是0进而判断大/小根堆;
3,AC代码
#include<bits/stdc++.h>
using namespace std;
int M, N, input[1005];
vector<int> ans; //记录后序遍历序列 注意初始化!
unordered_set<int> record; //记录是大根堆1还是小根堆0 注意初始化!
void judge(int index){
if(index > N) return;
if(2 * index <= N){
if(input[index] > input[2 * index]) record.insert(1);//1 大根堆
else record.insert(0); // 0小根堆
judge(2 * index);
}
if(2 * index + 1 <= N){
if(input[index] > input[2 * index + 1]) record.insert(1);//1 大根堆
else record.insert(0); // 0小根堆
judge(2 * index + 1);
}
ans.push_back(input[index]);
}
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
cin>>M>>N;
while(M--){
for(int i = 1; i <= N; i++)
scanf("%d", &input[i]);
record.clear();ans.clear(); // !!!初始化
judge(1);
if(record.size() == 1){ //说明不是大根堆就是小根堆
if(*record.begin() == 1)
printf("Max Heap\n");
else if(*record.begin() == 0)
printf("Min Heap\n");
}
else printf("Not Heap\n"); //说明既不是大根堆也不是小根堆
for(int i = 0; i < N; i++)
printf("%d%c", ans[i], i == N-1 ? '\n':' ');
}
return 0;
}
4,解题过程
一发入魂o(* ̄▽ ̄*)ブ