题目
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
题目补充说明
首先需要注意几个概念
二叉树的深度 是根节点到最远叶子节点的最长路径上的节点数。
二叉树的高度 是最远的叶子节点到该节点的最长简单路径边的条数。
如果说树的深度和高度,两者的数量是一致的;但是具体到某个节点,可能会有差别。
如图所示的二叉树,高度和深度都为3;但是节点4的高度是1,节点3的高度是2。
思路
因为要计算二叉树的深度,所以肯定需要考虑到每个节点的情况,这就需要遍历。
此外,还需要记录节点的路径数,并得到从根节点到叶子节点最长路径。
具体遍历的实现细节可以看这里:【数据结构】二叉树的前、中、后序、深度、广度遍历(图、文、代码)
代码实现
深度遍历方法(非递归 后序遍历)
/**
* 二叉树的深度 非递归
* @param root
* @return
*/
public int maxDepth(TreeNode root) {
//初始化辅助队列 进行后序遍历
Deque<TreeNode> treeDeque = new LinkedList<>();
TreeNode prev = null; //暂存最近访问过的节点
int maxDepth = 0; //节点深度 最终返回二叉树的深度
while(root != null || !treeDeque.isEmpty()){
if(root != null){
treeDeque.push(root); //根节点非空入队
root = root.left; //往左孩子走
}else{
root = treeDeque.getFirst(); //获得队尾元素但不出队
if(root.right == null || root.right == prev){ //右孩子为空或者右孩子已经被访问过
treeDeque.pop(); //出队
prev = root; //记录最近访问过的节点
root = null; //置空
}else{
root = root.right; //非空 往右孩子走
}
}
maxDepth = Math.max(maxDepth,treeDeque.size()); //比较交换
}
return maxDepth;
}
深度优先遍历(递归)
/**
* 二叉树的深度 递归
* @param root
* @return
*/
public int maxDepth(TreeNode root){
if(root == null){ //根节点为空 递归停止
return 0;
}else{
int leftDepth = maxDepth(root.left); //获得左子树的深度
int rightDepth = maxDepth(root.right); //获得右子树的深度
return Math.max(leftDepth,rightDepth) + 1; //选择左右子树大的一边加上根节点
}
}
总结
当非递归实现时,如果前中后序的变通,如果直接套模板会发现前中遍历根节点都会提前出队,就不能用获得队列长度的方法了(也可用前中遍历,再额外定义个变量记录一下)。
当然不管是深度优先还是广度优先都能够实现的,本质还是二叉树的遍历了。