判斷完全二叉樹和滿二叉樹
阿新 • • 發佈:2019-02-13
(一)判斷完全二叉樹
特點一:
只允許最後一層有空缺結點且空缺在右邊,即葉子結點只能在層次最大的兩層上出現;
特點二:
對任一結點,如果其右子樹的深度為j,則其左子樹的深度必為j或j+1 即度為1的點只有1個或0個
解題思路:
首先一棵空樹是完全二叉樹
利用佇列 先將根節點入隊 只要當前節點不為NULL 先從佇列front()得到一個節點 並將吹對節點的左右孩子入隊 如果存在只有一個孩子的情況 用NULL來代替那個孩子
如果當前節點為空了 則判斷佇列是否weiNULL
如果佇列也null了 那麼此棵樹就是完全二叉樹
隊還不為NULL那麼就直接front出隊 如果當前出隊的節點是NULL節點 則證明不是完全二叉樹
bool Is_Comp_BinaryTree(BtNode *ptr) { if(ptr == NULL) return true; queue<BtNode*> qu; qu.push(ptr); while(ptr != NULL)//只要節點不為NULL 就進行出隊 並且入出隊節點的左右孩子 { ptr = qu.front();qu.pop(); if(ptr != NULL) { qu.push(ptr->leftchild); qu.push(ptr->rightchild); } } while(!qu.empty())//節點NULL 但是佇列不空時 { ptr=qu.front();qu.pop(); if(ptr == NULL)//出隊節點為NULL 則證明不是一個完全二叉樹 入隊時 先入左 在入右 { return false; } } return true; }
(二)判斷滿二叉樹
空樹不是一棵滿二叉樹
每個節點都存在左右孩子 並且左右子樹深度要相同
遞迴程式碼
//遞迴 bool Is_Full_BinaryTree1(BtNode* ptr) { return (ptr == NULL) || (ptr != NULL && Is_Full_BinaryTree1(ptr->leftchild) && Is_Full_BinaryTree1(ptr->rightchild)) && Depth_BinTree(ptr->leftchild) == Depth_BinTree(ptr->rightchild); }
非遞迴思路
計算出樹的深度以及樹的節點個數num
然後根據深度求出如果為滿二叉樹應有的節點個數sum
如果num == sum那麼為滿二叉樹
bool Is_Full_BinaryTree2(BtNode* ptr)
{
if(ptr == NULL )
return false;
//求出數的深度
int k = Depth2(ptr);
//求出樹的節點個數
int num = Size_BinTree(ptr);
int sum = 0;
int count = 1;
//遍歷求出次數如果為滿二叉樹時的總節點數
//滿二叉樹下一層節點個數為上一層的2倍
for(int i = 0 ; i <= k ;++i)
{
sum += count;
count = count*2;
}
if(num == sum)
return true;
else
return false;
}
非遞迴用佇列實現
將樹的節點都入隊
然後按照滿二叉樹每一層的節點個數控制節點出隊 如果每一層都滿足節點數控制 那麼為滿二叉樹
只要存在一層不滿足出隊數量 就不是滿二叉樹
bool Is_Full_BinaryTree3( BtNode *ptr)
{
if(ptr == NULL)
return false;
int num = 1; //控制每一層的節點個數 從根節點開始 只有一個節點
queue<BtNode*> qu;
qu.push(ptr);
while(!qu.empty())
{
int i ;
for( i = 0 ; i < num && !qu.empty();++i)
{
while(!qu.empty())
{
ptr = qu.front();qu.pop();
if( ptr->leftchild != NULL)
{
qu.push(ptr->leftchild);
}
if(ptr->rightchild != NULL)
{
qu.push(ptr->rightchild);
}
}
}
//只要有一層出隊個數小於num那麼 就不是一棵滿二叉樹
if(i < num )
{
return false;
}
else
{
num *= 2;
}
}
return true ;
}