使用DFS
# 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;
}
使用algorithm中的is_heap函数
# include <bits/stdc++.h>
using namespace std;
int M, N;
vector<int> A(1001);
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;
A.resize(N+1);
for(int i = 0;i < M;++i){
for(int j = 1;j <= N;++j)
cin >> A[j];
bool isMaxHeap = is_heap(A.begin()+1, A.end());
bool isMinHeap = is_heap(A.begin()+1, A.end(), greater<int>());
if(isMaxHeap){
cout << "Max Heap" << endl;
} else
if(isMinHeap){
cout << "Min Heap" << endl;
} else
if(!isMaxHeap && !isMinHeap) {
cout << "Not Heap" << endl;
}
cnt = 0;
postTraverse(1);
}
return 0;
}
从后往前遍历判断当前结点是否大于等于父节点,否的话说明不是大根堆,返回false;
从后往前遍历判断当前结点是否小于父节点,否的话说明不是小根堆,返回false;
如果既不是大根堆也不是小根堆,那么说明就不是堆。
自写is_heap函数
# include <bits/stdc++.h>
using namespace std;
int M, N;
vector<int> A(1001);
int cnt;
void postTraverse(int root){ // 后序遍历
if(root > N) return;
postTraverse(root*2);
postTraverse(root*2 + 1);
cout << A[root] << (cnt++ == N-1 ? "\n" : " ");
}
bool is_max_heap(){
for(int i = N;i >= 2;--i)
if(A[i/2] < A[i])
return false;
return true;
}
bool is_min_heap(){
for(int i = N;i >= 2;--i)
if(A[i/2] >= A[i])
return false;
return true;
}
int main() {
cin >> M >> N;
A.resize(N+1);
for(int i = 0;i < M;++i){
for(int j = 1;j <= N;++j)
cin >> A[j];
bool isMaxHeap = is_max_heap();
bool isMinHeap = is_min_heap();
if(isMaxHeap){
cout << "Max Heap" << endl;
} else
if(isMinHeap){
cout << "Min Heap" << endl;
} else
if(!isMaxHeap && !isMinHeap) {
cout << "Not Heap" << endl;
}
cnt = 0;
postTraverse(1);
}
return 0;
}