面试题39:二叉树的深度、判断二叉树是不是平衡

题目一:

 1 int TreeDepth(BinaryTreeNode* pRoot)
 2 {
 3     if(pRoot == NULL)
 4         return 0;
 5 
 6     int nLeft = TreeDepth(pRoot->m_pLeft);
 7     int nRight = TreeDepth(pRoot->m_pRight);
 8 
 9     return (nLeft > nRight) ? (nLeft + 1) : (nRight + 1);
10 }

题目二:判断二叉树是不是平衡

法一:利用TreeDepth判断

 

 1 bool IsBalanced(BinaryTreeNode* pRoot)
 2 {
 3     if(pRoot== NULL)
 4         return true;
 5 
 6     int nLeftDepth = TreeDepth(pRoot->m_pLeft);
 7     int nRightDepth = TreeDepth(pRoot->m_pRight);
 8     int diff = nRightDepth-nLeftDepth;
 9 
10     if (diff>1 || diff<-1)
11         return false;
12 
13     return IsBalanced(pRoot->m_pLeft)&&IsBalanced(pRoot->m_pRight);
14 }

上面的代码固然简洁,但我们也要注意到由于一个节点会被重复遍历多次,这种思路的时间效率不高。例如在函数IsBalance中输入上图中的二叉树,首先判断根结点(值为1的结点)的左右子树是不是平衡结点。此时我们将往函数TreeDepth输入左子树根结点(值为2的结点),需要遍历结点4、5、7。接下来判断以值为2的结点为根结点的子树是不是平衡树的时候,仍然会遍历结点4、5、7。毫无疑问,重复遍历同一个结点会影响性能。接下来我们寻找不需要重复遍历的算法。

 

法二:后序遍历

由于上述方法在求该结点的的左右子树深度时遍历一遍树,再次判断子树的平衡性时又遍历一遍树结构,造成遍历多次。因此方法二是一边遍历树一边判断每个结点是否具有平衡性

判断左子树和右子树是否是平衡二叉树,是的话更新深度

 1 bool IsBalanced(TreeNode* pRoot,int &depth)
 2     {
 3         if(pRoot == NULL)
 4         {
 5             depth = 0;
 6             return true;
 7         }
 8         int leftDepth,rightDepth;
 9         bool left = IsBalanced(pRoot->left,leftDepth);
10         bool right = IsBalanced(pRoot->right,rightDepth);
11         if(left && right)
12         {
13             int dif = leftDepth - rightDepth;
14             if(dif <= 1 && dif >= -1)
15             {
16                 depth = (leftDepth > rightDepth ? leftDepth : rightDepth) + 1;
17                 return true;
18             }
19         }
20         return false;
21     }
22     bool IsBalanced_Solution(TreeNode* pRoot) 
23     {
24         int depth = 0;
25         return IsBalanced(pRoot,depth);
26     }

 

posted on 2016-07-18 16:33  已停更  阅读(226)  评论(0编辑  收藏  举报