题目一:
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 }