1、遍历一棵树
树相关的所有问题都可以总结为遍历一棵树,然后对其进行相关操作。遍历一棵树总体可以分为两种:递归遍历(前中后序遍历)以及迭代遍历(层序遍历)。具体采用哪种遍历方式需要根据具体问题分析。
2、遍历框架
2.1、递归遍历(前中后序遍历)
递归遍历一棵树根据访问根节点的先后次序可分为前序遍历(根左右)、中序遍历(左根右)以及后序遍历(左右根)。
这三种遍历方式都可以用这个框架表示:
public TreeNode traversal(TreeNode root){
// 前序遍历
traversal(root.left);
// 中序遍历
traversal(root.right);
// 后序遍历
2.2、层序遍历
层序遍历的含义为从根到叶子节点,一层一层的遍历一棵树,因此我们可以采用队列这种数据结构来层序遍历一棵树,代码框架如下:
public TreeNode[] traversal(TreeNode root){
// 核心数据结构为队列
Queue<TreeNode> queue = new LinkedList<>();
if(root == null) return;
queue.offer(root);
while(!queue.isEmpty()){
// 出队
TreeNode cur = queue.poll();
// 左右孩子入队
if(cur.left != null)
queue.offer(cur.left);
if(cur.right != null)
queue.offer(cur.right);
}
}
3、实例
3.1 递归遍历
这个例子是leetcode124:二叉树的最大路径和。下面是具体代码:
class Solution {
// 递归计算经过每个节点的最大路径和,再用一个变量记录最大值
private int maxValue = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
calculatePathValue(root);
return maxValue;
}
public int calculatePathValue(TreeNode root) {
if (root == null) {
return 0;
}
// 计算从左边以及右边过来的最大值
int leftPathValue = Math.max(calculatePathValue(root.left), 0);
int rightPathValue = Math.max(calculatePathValue(root.right), 0);
int nodeMaxValue = root.val + leftPathValue + rightPathValue;
maxValue = Math.max(maxValue, nodeMaxValue);
// 由于计算的是单边的最大值,因此返回的是左边或者右边子树的最大值
return root.val + Math.max(leftPathValue, rightPathValue);
}
}
上面的代码总的来说就是一个后序遍历,先计算左子树及右子树的最大路径和,然后再将其与根节点的值相加。只不过在递归返回的时候,我们返回的是单边子树及根节点值的和。
3.2、层次遍历
这个例子是leetcode102 二叉树的层次遍历:
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> ans = new ArrayList<List<Integer>>();
if(root == null)
return ans;
// BFS,广度优先搜索,用队列来实现。
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
while(!queue.isEmpty()){
List<Integer> level = new ArrayList<Integer>();
int leverSize = queue.size();
for(int i = 1; i <= leverSize; i++){
TreeNode node = queue.poll();
level.add(node.val);
if(node.left != null){
queue.offer(node.left);
}
if(node.right != null){
queue.offer(node.right);
}
}
ans.add(level);
}
return ans;
}
}
层次遍历实际上就是BFS,BFS的核心就是一层一层往外遍历,因此可以用队列来实现,以上是具体代码。