1. 程式人生 > >判斷完全二叉樹和滿二叉樹

判斷完全二叉樹和滿二叉樹

(一)判斷完全二叉樹

特點一:

只允許最後一層有空缺結點且空缺在右邊,即葉子結點只能在層次最大的兩層上出現; 

特點二:

對任一結點,如果其右子樹的深度為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 ;
}