1、题目:输入一颗二叉树的根结点,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};
例如图示的二叉树的深度为4,因为它从根结点到叶结点最长的路径包含4个结点(从根结点1开始,经过结点2和5,最终到达叶结点7)。
1
2 3
4 5 6
7
解法:
如果一棵树只有一个结点,它的深度为1。如果根结点只有左子树而没有右子树,那么树的深度应该是其左子树的深度加1;右子树同理。如果左右子树都有,则深度就是其左右子树的较大值再加1。
int TreeDepth(BiaryTreeNode* pRoot)
{
if(pRoot == NULL)
return 0;
int nLeft = TreeDepth(pRoot->m_pLeft);
int nRight = TreeDepth(pRoot->m_pRight);
return (nLeft > nRight) ? (nLeft + 1) : (nRight + 1);
}
2、题目:输入一颗二叉树的根结点,判断其是不是平衡二叉树。如果某二叉树中任意结点的左右子树的深度相差不超过1,他就是一颗平衡二叉树。题目一图示的就是一颗平衡二叉树。
解法一:
在遍历树的每个结点时,调用函数TreeDepth得到他的左右子树的深度。如果每个结点的左右子树的深度相差不超过1,按照定义它就是平衡二叉树。
int IsBalanced(BiaryTreeNode* pRoot)
{
if(pRoot == NULL)
return true;
int left = TreeDepth(pRoot->m_pLeft);
int right = TreeDepth(pRoot->m_pRight);
int diff = left - right;
if(diff > 1 || diff < -1)
return false;
return IsBalanced(pRoot->m_pLeft) && IsBalanced(pRoot->m_pRight);
}
此代码虽然简洁,但一个结点会被重复遍历多次,故时间效率不高。
解法二:
如果我们用后续遍历的方式遍历二叉树的每一个结点,在遍历到一个结点之前我们就已经遍历了它的左右子树。只要在遍历每个结点的时候记录它的深度(某一结点的深度等于它到叶结点的路径的长度),我们就可以一边遍历一边判断每个结点是不是平衡的。
int IsBalanced(BiaryTreeNode* pRoot, int* pDepth)
{
if(pRoot == NULL)
{
*pDepth = 0;
return true;
}
int left, right;
if(IsBalanced(pRoot->m_pLeft, &left)
&& IsBalanced(pRoot->m_pRight, &right))
{
int diff = left - right;
if(diff <= 1 && diff >= -1)
{
*pDepth = 1 + (left > right ? left : right);
return true;
}
}
return false;
}
我们只需给上面的函数传入二叉树的根结点及一个表示结点深度的整型变量即可:
bool IsBalanced(BiaryTreeNode* pRoot, int* pDepth)
{
int depth = 0;
return IsBalanced(pRoot, &depth);
}