二叉树的深度

本文介绍了如何计算二叉树的深度及判断是否为平衡二叉树的方法。包括递归求解二叉树深度的算法实现,并提出了两种判断平衡性的方案:一种通过重复遍历结点,另一种通过后序遍历确保每个结点仅被遍历一次。

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

题目一:输入一课二叉树的根结点,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

二叉树的结点定义如下:

struct BinaryTreeNode
{
	int m_nValue;
	BinaryTreeNode* m_pLeft;
	BinaryTreeNode* m_pRight;
}
思路:如果一棵树只有一个结点,它的深度为1。如果根结点只有左子树而没有右子树,那么树的深度应该是左子树的深度加1;同样如果结点只有右子树而没有左子树,那么树的深度应该是其右子树的深度加1;如果有左子树和右子树,深度就是左右子树的较大值加1。代码如下:
int TreeDept(BinaryTreeNode* pRoot)
{
	if(pRoot==NULL)
		return 0;
	int left=TreeDept(pRoot->m_pLeft);
	int right=TreeDept(pRoot->m_pRight);
	
	return (left>right)?(left+1):(right+1);


}

测试用例:

功能测试(输入普通的二叉树,二叉树中所有结点都没有左/右子树)

特殊输入测试(二叉树只有一个结点,二叉树的头结点为NULL指针)。

题目二:输入一棵二叉树的根结点,判断该树是不是平衡二叉树。如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。

分析:

解法一:需要重复遍历结点多次的解法

有了求二叉树深度的经验之后,我们很容易想到一个思路:在遍历树的每一个结点的时候,调用TreeDepth得到它的左右子树的深度。如果每一个结点的左右子树的深度相差不超过1,按照定义它就是一棵平衡二叉树。这种思路对应代码如下:

bool IsBalanced(BinaryTreeNode* pRoot)
{
	if(pRoot==NULL)
		return true;
	int left=TreeDept(pRoot->m_pLeft);
	int right=TreeDept(pRoot->m_pRight);
	int diff=left-right;
	if(diff>1 || diff<-1)
		return false;
	
	return IsBalanced(pRoot->m_pLeft) && IsBalanced(pRoot->m_pRight);
}
上面的代码虽然简洁,但是我们也要注意到由于一个结点会被重复遍历多次,这种思路的时间效率不高。

解法二:每一个结点只遍历一次的解法

如果我们使用后序遍历的方式遍历二叉树的每一个结点,在遍历的一个结点之前我们就已经遍历了它的左右子树。只要在遍历每一个结点的时候记录它的深度(某一个结点的深度等于它到叶子结点的路径的长度),我们就可以一边遍历,一边判断每一个结点是不是平衡的。代码如下:

bool IsBalanced(BinaryTreeNode* pRoot,int* pDept)
{
	if(pRoot==NULL )
	{
		*pDept=0;
		return true;
	}
		
	int left;
	int right;
	if(IsBalanced(pRoot->m_pLeft,&left)&&IsBalanced(pRoot->m_pRight,&right))
	{
		int diff=left-right;
		if(diff>=1 || diff<=-1)
		{
			*pDept=1+(left>right?left:right);
			return true;
		}
	}
	return false;
}
我们只需要给上面的函数传入二叉树的根结点以及表示结点深度的整型变量即可:

bool IsBalanced(BinaryTreeNode* pRoot)
{
	int dept=0;
	return IsBalanced(pRoot,&dept);
}
测试用例:

功能测试(平衡二叉树,不是平衡二叉树,二叉树中所有结点都没有左右子树)

特殊输入测试(二叉树中只有一个结点,二叉树的头结点为NULL指针)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值