二叉树遍历
二叉树的遍历分为深度优先和广度优先
深度优先又分为前序遍历、中序遍历和后序遍历
详见:初识二叉树
我们可以理解为对结点的处理顺序在前、中间还是最后
例如:
前序遍历
递归
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
if(root == null){
return list;
}
list.add(root.val);
List<Integer> left = preorderTraversal(root.left);
List<Integer> right =preorderTraversal(root.right);
list.addAll(left);
list.addAll(right);
return list;
}
非递归
思路:
我们提前准备一个栈,保存所经过的路径,然后从根节点一直向左出发,当左孩子为空,然后找右孩子,然后回溯,直到找完。
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
if(root == null) {
return list;
}
TreeNode cur = root;
Stack<TreeNode> stack = new Stack<>();
while(cur != null || !stack.isEmpty()){
while(cur != null){
stack.push(cur);
list.add(cur.val);
cur = cur.left;
}
TreeNode pop = stack.pop();
cur = pop.right;
}
return list;
}
}
中序遍历
递归
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
if (root == null) {
return list;
}
List<Integer> left = inorderTraversal(root.left);
list.addAll(left);
list.add(root.val);
List<Integer> right = inorderTraversal(root.right);
list.addAll(right);
return list;
}
非递归
思路:
我们提前准备一个栈,保存所经过的路径,然后从根节点一直向左出发,当左孩子为空,然后找右孩子,然后回溯,直到找完。
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
if (root == null) {
return list;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
TreeNode node = stack.pop();
list.add(node.val);
cur = node.right;
}
return list;
}
后序遍历
递归
public List<Integer> postorderTraversal1(TreeNode root) {
List<Integer> list = new ArrayList<>();
if (root == null) {
return list;
}
List<Integer> left = postorderTraversal(root.left);
list.addAll(left);
List<Integer> right = postorderTraversal(root.right);
list.addAll(right);
list.add(root.val);
return list;
}
非递归
思路:
相比之下,后序遍历的非递归比前两个要麻烦一点,因为不是简单的删除栈顶元素,如果处理不好会造成死循环,所以我们需要判断右孩子是否为空,和是否刚走过右孩子。
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
if (root == null) {
return list;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
TreeNode last = null;
while (cur != null || !stack.isEmpty()) {
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
TreeNode node = stack.peek();
if (node.right == null || node.right == last) {
// 看作第三次经过
list.add(node.val);
last = node;
stack.pop();
} else {
// 第二次经过
cur = node.right;
}
}
return list;
}