table of Contents
Binary tree traversal
Binary tree traversal into depth-first and breadth-first
depth-first traversal is divided into the preamble, preorder and postorder
See: acquaintance binary tree
We can understand that the processing order of the nodes is first, middle or last.
For example:
Preorder traversal
Preorder traversal of binary tree
Recursion
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;
}
Non-recursive
Idea:
We prepare a stack in advance, save the path passed, and then start from the root node all the way to the left, when the left child is empty, then find the right child, and then backtrack until the end is found.
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;
}
}
In-order traversal
In-order traversal of binary tree
Recursion
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;
}
Non-recursive
Idea:
We prepare a stack in advance, save the path passed, and then start from the root node all the way to the left, when the left child is empty, then find the right child, and then backtrack until the end is found.
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;
}
Post-order traversal
Post-order traversal of binary tree
Recursion
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;
}
Non-recursive
Idea:
In contrast, the non-recursive post-order traversal is a bit more troublesome than the first two, because it is not simply deleting the top element of the stack, if it is not handled well, it will cause an infinite loop, so we need to judge whether the right child is empty, and Have you just walked past the right child.
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;
}