判断完全二叉树是不是一个堆
完全二叉树适合用数组存储,而且从第二个位置及a[1]开始存储,这样对于一个节点i
,它的左子树和右子树就分别为i*2
和i*2+1
。
对于一个完全二叉树存储的树结构,可以用如下方法来它是不是一个堆。
方法1:
bool isMinHeap(int root){
if(root*2>n) return true;//叶节点
if(root*2<=n&&root*2+1<=n&&cb[root]<=cb[root*2]&&cb[root]<=cb[root*2+1]){//有左右子树
return isMinHeap(root*2)&&isMinHeap(root*2+1);
}else if(root*2==n&&cb[root]<=cb[root*2]){//仅有左子树 //考试时判断的是root*2<=n,导致一个测试点错误,如输入的3个节点为2 3 1
return true; //所以一定要认真分析,这一步就是判断只有左子树的情况。
}else{
return false;
}
}
bool isMaxHeap(int root){
if(root*2>n) return true;
if(root*2<=n&&root*2+1<=n&&cb[root]>=cb[root*2]&&cb[root]>=cb[root*2+1]){
return isMaxHeap(root*2)&&isMaxHeap(root*2+1);
}else if(root*2==n&&cb[root]>=cb[root*2]){
return true;
}else{
return false;
}
}
调用时直接直接将树根1传入就行了。
上面是考试时想到的方法,有点麻烦,下面是别人更简洁的方法。
方法二:
bool isMaxH=true,isMinH=true;
for(int i=2;i<=n;i++){
if(cb[i/2]<cb[i]){
isMaxH=false;
}
if(cb[i/2]>cb[i]){
isMinH=false;
}
}
if(isMinH){
cout<<"Min Heap"<<endl;
}else if(isMaxH){
cout<<"Max Heap"<<endl;
}else{
cout<<"Not Heap"<<endl;
}