剑指offer -- 二叉树的深度(求一棵二叉树的深度+判断一棵二叉树是否是平衡二叉树)

题目一:二叉树的深度
输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。如图所示的二叉树深度为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);
}

猜你喜欢

转载自blog.csdn.net/scarificed/article/details/120651329