完全二叉树的节点数量

1.题目

一棵完全二叉树的节点总数
题意:已知一棵完全二叉树,求其节点的个数
要求:时间复杂度低于O(N),N为这棵树的节点个数。
公式节点个数=2^n-1

2.思路

低于O(N) 那么我们不可能用层序遍历去求解
我们可以用满二叉树的计算公式去求解
求解完全二叉树的深度

int GetLeftHeight(NODE *Head, int Level)
{
    
    
	while(NULL != Head)
	{
    
    
		Level++;
		Head = Head->Left;		
	}
	
	return Level - 1;
}

我们知道一颗完全二叉树的深度 等于他最左节点的深度
如果当前节点的右子树的最左节点不是空,那么这个节点的左子树一定是满二叉树,右子树是完全二叉树递归求解
如果当前节点的右子树的最左节点是空,那么右子树一定是满二叉树,左子树是完全二叉树,递归求解

3.代码

int CB(NODE *Head, int Level, int TotalHeight)
{
    
    
	//递归出口 当当前的层数和总层数相同 
	if(Level == TotalHeight)
		return 1;
	
	//如果右子树上的高度 == 左子树的高度 那么左子树就是一个满二叉树
	//2^n - 1 + 1(根)  那么右子树就是一颗完全二叉树 递归求解 
	if(GetLeftHeight(Head->Right, Level+1)  == TotalHeight)
		return (1<< (TotalHeight-Level)) + 
		CB(Head->Right, Level+1, TotalHeight);
	//如果不是 那么右子树 肯定是一个满二叉树 左子树是一个完全二叉树
	//递归求解 右子树比左子树 少一层 
	else
		return (1<< (TotalHeight-Level-1)) + 
		CB(Head->Right, Level+1, TotalHeight);
}

int CountB(NODE *Head)
{
    
    
	if(NULL == Head)
		return 0;
	
	return CB(Head, 1, GetLeftHeight(Head, 1));	
} 
int main(int argc, char** argv) 
{
    
    
	string Str = "1_2_4_#_#_5_#_#_3_6_#_#_7_#_#_";	
	queue<string> Queue;
 
	split (Str, Queue);
	NODE *Head = ReconPreOrder(Queue);
	//PreOrder(Head);
	//InOrder(Head);
	//PosOrder(Head);
	
	string Str1 = "1_2_#_#_3_4_#_#_5_#_#_";
	split (Str1, Queue);
	NODE *Head1 = ReconPreOrder(Queue);
	
	if(IsComplete(Head))
	{
    
    
		cout<<"是一个完全二叉树 ";
		cout<<"节点个数为 "<<CountB(Head)<<endl;
	}
	else
	{
    
    
		cout<<"不是一个完全二叉树"<<endl;	
	} 
	
	if(IsComplete(Head1))
	{
    
    
		cout<<"是一个完全二叉树 ";
		cout<<"节点个数为 "<<CountB(Head1)<<endl;
	}
	else
	{
    
    
		cout<<"不是一个完全二叉树"<<endl;	
	} 
		
	return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/ZZHinclude/article/details/119773386