前言
二叉树遍历有递归遍历和层次遍历,这是操作二叉树的基础。
一、找树左下角的值
二、遍历+改进
1、前序遍历
// 找树左下角的值。
public class FindBottomLeftValue {
/*
target:找出二叉树最下最左边的值。
该值特点:深度最大。
如何拿到深度最大的节点值?通过遍历,在遍历的过程中传入深度变量,用一个变量记录最大深度那个节点值。
当同深度有多个值时,如何拿到最左边那个值?可通过前序遍历的方式去寻找更深的节点,当深度一样时,还是保持第一次记录的节点值。
*/
public int findBottomLeftValue(TreeNode root) {
// 记录当前遍历过程中最左最深的节点值。
// 初始化为根节点值,深度为1.
int[] rs = new int[]{root.val, 1};
// 前序遍历寻找更深的节点值。
preOrder(root, 1, rs);
// 返回最深最左的节点值。
return rs[0];
}
/**
* @param root 树根节点。
* @param level 当前所在树的深度。
* @param rs 存储最左最深的节点值和深度。
*/
private void preOrder(TreeNode root, int level, int[] rs) {
if (null == root) return;
// 在前序遍历的基础上对最深最左节点进行更新。
if (rs[1] < level) {
rs[0] = root.val;
// 根据前序遍历特点,能比当前记录的还深的节点,一定在下一层。
++rs[1];
}
// 先左后右。
preOrder(root.left, level + 1, rs);
preOrder(root.right, level + 1, rs);
}
// Definition for a binary tree node.
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {
}
TreeNode(int val) {
this.val = val;
}
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
}
2、层次遍历
// 练习一下层次遍历。
class FindBottomLeftValue2 {
/*
target:找出二叉树最下最左边的值。
该值特点:深度最大。
如何拿到深度最大的节点值?通过遍历,在遍历的过程中传入深度变量,用一个变量记录最大深度那个节点值。
当同深度有多个值时,如何拿到最左边那个值?可通过层次遍历拿最后一层的第一个节点的值即可。
如何拿最后一层的第一个节点的值?可每次记录当前层的头节点的值。
如何分层?通过每层有多少节点数,访问一个就减一来判是否马上开启新一层的遍历。
*/
public int findBottomLeftValue(TreeNode root) {
// 层次遍历,按队列的出入方式来进行。
Queue<TreeNode> que = new LinkedList<>();
// 初始化第一层节点。
que.add(root);
// 记录当前层的节点个数,当前层为第一层,只有root节点。
int curSize = 1;
// 记录第一层的第一个节点的值。该节点为root。
int leftNodeVal = root.val;
// 以循环的方式开启层次遍历。
while (!que.isEmpty()) {
// 从左到右遍历当前层节点。
TreeNode node = que.poll();
// 将左右非空孩子加入层次遍历的路径中。
if (null != node.left) que.add(node.left);
if (null != node.right) que.add(node.right);
// 更新当前层还剩余未遍历的节点数,并根据情况完成下一层节点数的更新和最左节点值的更新。
if (--curSize == 0) {
curSize = que.size();
// 由于循环所需,que此时可能已经为空,更下一层就没有了。
if (!que.isEmpty()) leftNodeVal = que.peek().val;
}
}
// 返回最深一层的第一个节点值。
return leftNodeVal;
}
// Definition for a binary tree node.
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {
}
TreeNode(int val) {
this.val = val;
}
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
}
总结
1)经典前序遍历+分层遍历。
参考文献
[1] LeetCode 找树左下角的值