①后序遍历的递归出口别忘了判断root是否超过树结点最大值
②注意堆的存储从1开始,看成完全二叉树
#include<bits/stdc++.h>
using namespace std;
int heap[110][1100];
vector<int> res;
bool maxheap(int i,int n){
for(int j=n;j>=2;j--){
if(heap[i][j]>heap[i][j/2])
return false;
}
return true;
}
bool minheap(int i,int n){
for(int j=n;j>=2;j--){
if(heap[i][j]<heap[i][j/2])
return false;
}
return true;
}
void posttraverse(int i,int n,int root){
if(root>n) return; //递归出口,到达最左下的孩子,或者超出树结点
if(2*root>n)
{
res.push_back(heap[i][root]);
return;
}
posttraverse(i,n,root*2);
posttraverse(i,n,root*2+1);
res.push_back(heap[i][root]);
}
int main(){
int m,n;
cin>>m>>n;
for(int i=0;i<m;i++){
for(int j=1;j<=n;j++){
cin>>heap[i][j];
}
if(maxheap(i,n)) cout<<"Max Heap"<<endl;
else if(minheap(i,n)) cout<<"Min Heap"<<endl;
else cout<<"Not Heap"<<endl;
res.clear();
posttraverse(i,n,1);
for(int k=0;k<res.size();k++){
if(k!=0)
cout<<" "<<res[k];
else cout<<res[k];
}
cout<<endl;
}
}
复习后知道,堆的存储数列就是堆的层序遍历,可以通过中序遍历建堆
判断是否为堆的时候从下网上,类似upAdjust更方便
#include<bits/stdc++.h>
using namespace std;
vector<int> ans;
int min1=1,max1=1;
void judegeheap(vector<int> temp){
int n=temp.size();
for(int i=n-1;i>1;i--){
if(temp[i]>temp[i/2]) max1=0;
if(temp[i]<temp[i/2]) min1=0;
}
}
void postorder(vector<int> &temp,int now){
if(now>=temp.size()) return;
postorder(temp,now*2);
postorder(temp,now*2+1);
ans.push_back(temp[now]);
}
int main(){
int test,n;
cin>>test>>n;
for(int j=0;j<test;j++){
vector<int> v(n+1);
for(int i=1;i<=n;i++)
cin>>v[i];
max1=1;
min1=1;
judegeheap(v);
if(max1==1&&min1==0) cout<<"Max Heap"<<endl;
else if(max1==0&&min1==1) cout<<"Min Heap"<<endl;
else cout<<"Not Heap"<<endl;
ans.clear();
postorder(v,1);
for(int k=0;k<ans.size();k++){
if(k) cout<<" ";
cout<<ans[k];
}
cout<<endl;
}
}