完全二叉树的节点数量

本文介绍了一种利用完全二叉树特性,通过递归计算节点个数的方法,时间复杂度低于O(N),适用于已知完全二叉树结构。关键步骤包括判断左右子树的深度关系,确定满二叉树部分并递归求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值