因为求深度可以从上到下去查所以需要前序遍历(中左右),⽽⾼度只能从下到上去查,所以只能后序遍历(左右中)
有的同学⼀定疑惑,为什么求⼆叉树的最⼤深度时也⽤的是后序遍历。
那是因为代码的逻辑其实是求的根节点的⾼度,⽽根节点的⾼度就是这棵树的最⼤深度,所以才可以使⽤后序遍历。
如果真正求取⼆叉树的最⼤深度,代码应该写成如下:(前序遍历)
class Solution{
public:
int result;
void getDepth(TreeNode* node,int depth) {
result=depth>result? depth:result;//中
if(node->left==NULL&&node->right==NULL) return;
if(node->left) {//左
depth++;
getDepth(node->left,depth);
depth--;//回溯,深度-1
}
if(node->right){
depth++;
getDepth(node->right,depth);
depth--;
}
return;
}
int maxDepth(TreeNode*root) {
result=0;
if(root==0) return result;
getDepth(root,1);
return result;
}
};
递归法
1、明确递归函数的参数和返回值
参数为传⼊的节点指针,返回值要返回的是以传⼊节点为根节点树的高度。
那么如何标记左右⼦树是否差值⼤于1呢?
如果当前传⼊节点为根节点的⼆叉树已经不是⼆叉平衡树了,可以返回-1来标记已经不符合平衡树的规则了。代码如下:
int getHeight(TreeNode* node)
2、明确终⽌条件
递归的过程中依然是遇到空节点了为终⽌,返回0,表示当前节点为根节点的树的⾼度为0代码如下:
if(node==nullptr) return 0;
3、明确单层递归的逻辑
如何判断以当前传⼊节点为根节点的⼆叉树是否是平衡⼆叉树呢,当然是左⼦树⾼度和右⼦树⾼度差值小于等于1。
分别求出左右⼦树的⾼度,然后如果差值⼩于等于1,则返回当前⼆叉树的⾼度,否则则返回-1,表示已经不是⼆叉树了。
代码如下:
int leftHeight=getHeight(node->left);
if(leftHeight==-1) return -1;
int rightHeight=getHeight(node->right);
if(rightHeight==1) return -1;
return abs(leftDepth - rightDepth) > 1 ? -1 : 1 + max(leftDepth, rightDepth);
//abs 函数是存在于多种编程语言中的一种用于求数据绝对值的函数。
完整递归代码
class Solution{
public:
//返回以该节点为根节点的⼆叉树的⾼度,如果不是⼆叉搜索树了则返回-1
int getHeight(TreeNode*node) {
if(node==NULL) return 0;
int leftHeight=getHeight(node->left);
if(leftHeight==-1) return -1;//说明左⼦树已经不是⼆叉平衡树
int rightHeight=getHeight(node->right);
if(rightHeight==-1) return -1;//说明右⼦树已经不是⼆叉平衡树
return abs(leftHeight-rightHeight)>1? -1:1+max(leftHeight,rightHeight);
}
bool isBalanced(TreeNode*root) {
return getHeight(root)==-1? false:true;
}
};
总结
关于迭代法什么时候用队列什么时候用栈:
如果是模拟前中后序遍历就⽤栈,如果是适合层序遍历就⽤队列,当然还有其他情况,那么就是先⽤队列试试⾏不⾏,不⾏就⽤栈。
⼆叉树节点的深度:指从根节点到该节点的最⻓简单路径边的条数。
⼆叉树节点的⾼度:指从该节点到叶⼦节点的最⻓简单路径边的条数。