感觉网上太多答案都是完全参考柳神的版本。。。
柳神dfs部分可读性其实很一般,原因在于并不需要用到栈;我在最后给出我的模仿版本(不需要用栈)
出彩的是判断大顶堆和小顶堆,非堆的思路,这很值得借鉴
分析
DFS原理:参考这篇 PAT 1130 Infix Expression——什么才是DFS?由“柳神遍历”写法引发的思考
判断部分:排除法思路
初始化小顶堆和大顶堆为true;一点点排除,发现一个不是则为false
原因:小顶堆、大顶堆、非堆三者相互独立
我一开始思路:设定4个flag判断 左边大于、左边小于、右边大于,右边小于,来进行前后比较
是无法应对来回变化的,原因是flag会在 是和不是之间反复横跳
而用柳神的思路,一旦不是则固定下来
其中注意:静态树/堆一般从1号位开始放
代码
#include<bits/stdc++.h>
using namespace std;
int quantity;
vector<int>heap;
void InPut();
void LevelPrint(int, vector<int>);
int main() {
InPut();
vector<int>print;
LevelPrint(1, print);
bool is_min{ true }, is_max{ true };
for (int i = 2; i <= quantity; i++) {
heap[i / 2] > heap[i] ? is_min = false : is_max = false;
}
if (is_min)
printf("Min Heap");
else
printf("%s", is_max ? "Max Heap" : "Not Heap");
return 0;
}
void InPut() {
scanf("%d", &quantity);
heap.resize(quantity + 1);
for (int i = 0; i < quantity; i++)
scanf("%d", &heap[i + 1]);
}
void LevelPrint(int start, vector<int>print) {
print.push_back(heap[start]);
if (2 * start <= quantity && 2 * start + 1 <= quantity) {
LevelPrint(2 * start + 1, print);
LevelPrint(2 * start, print);
}
if (2 * start <= quantity && !(2 * start + 1 <= quantity)) {
LevelPrint(2 * start, print);
}
if (!(2 * start <= quantity) && 2 * start + 1 <= quantity) {
LevelPrint(2 * start + 1, print);
}
if (!(2 * start <= quantity) && !(2 * start + 1 <= quantity)) {
for (int i = 0; i < print.size();i++)
i == 0 ? printf("%d", print[i]) : printf(" %d", print[i]);
print.pop_back();
printf("\n");
}
}
柳神的思路——直接用1个vector即可
接口自己调用下,肯定是可以用的,
Print函数是一个输出接口
void PrintHeap(int sit, vector<int>store) {
store.push_back(Heap[sit]);
if (2 * sit > quantity + 1) {
Print(store);
return;
}
if (2 * sit + 1 < quantity + 1) {
PrintHeap(2 * sit + 1, store);
}
PrintHeap(2 * sit, store);
return;
}