题目一:二叉树的深度
输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。如图所示的二叉树深度为4, 从根节点到叶节点最长的路径包含4个节点 。(1 -> 2 -> 5 -> 7)
如果一棵树只有一个节点 那么它的深度为1,如果根节点只有左子树没有右子树,那么树的深度是其左子树深度加1。同样如果根节点只有右子树没有左子树,那么树的深度是其右子树深度加1。如果既有左子树又有右子树,那么树的深度就是左右子树深度较大的值加1。这种思路用递归很容易实现。
int TreeDepth(TreeNode * root){
if(root == NULL)
return 0;
int nleft = TreeDepth(root -> left);
int nright = TreeDepth(root -> right);
return (nleft > nright) ? (nleft + 1) : (nright + 1);
}
如果你不太理解递归这种算法,那我们从另一个角度来理解深度这个定义,深度就等于这棵二叉树拥有的层数。这棵二叉树有几层它的深度就是多少。二叉树的层序遍历改一下就是这道题的解法了 。
int TreeDepth(TreeNode* root) {
if(root == NULL) return 0;
int ans = 0;
queue<TreeNode*>q;
q.push(root);
while(!q.empty()){
int n = q.size();
for(int i = 1;i <= n;i++){
root = q.front();
if(root -> left != NULL){
q.push(root -> left);
}
if(root -> right != NULL){
q.push(root -> right);
}
q.pop();
}
ans++;
}
return ans;
}
题目二:平衡二叉树
输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。
如图一棵平衡二叉树
有了求二叉树的深度的经验之后在解决这个问题,我们很容易就可以想到,在遍历每个树的节点的时候,计算它的左右子树深度。如果每个节点的左右子树的深度相差都不超过1。那么这棵二叉树就是一棵平衡二叉树。
bool IsBalance(TreeNode * root){
if(root == NULL)
return true;
int nleft = TreeDepth(root->left);
int right = TreeDepth(root->right);
int diff = nleft - nright;
if(abs(diff)>1)
return false;
return IsBalance(root->left) && IsBalance(root->right);
}
上述代码固然简洁,但是一个节点会被重复遍历多次,这种思路时间效率不高。如我们判断根节点1是不是平衡的,此时我们向函数TreeDepth输入根节点的左子节点2时需要遍历4、 5、7。接下来判断以节点2为根节点的子树是不是平衡的时候,仍然会遍历节点 4、5、7。
如果我们用后序遍历的方式遍历二叉树的每个节点,那么在遍历到一个节点以前我们就已经遍历过了它的左右子树。可以根据它的左右子树的深度判断它是不是平衡的,然后得到当前节点的深度,最后遍历到根节点的时候,也就判断了整棵二叉树是不是平衡二叉树。
bool IsBalance(TreeNode *root ,int *pDepth){
if(root == NULL){
*pDepth = 0;
return true;
}
int nleft = 0;
int nright = 0;
if(IsBalance(root -> left,&nleft) && IsBalance(root -> right,&nright))
{
int diff = nleft - nright;
if(abs(diff) <= 1){
*pDepth = 1 + (nleft > nright ? nleft : nright);
return true;
}
}
return false;
}
我们只需要给上面的函数传如二叉树的根节点,以及一个表示深度的整形变量即可。
bool IsBalance(TreeNode * root){
int depth = 0;
return IsBalance(root,&depth);
}