1. 二叉树遍历代码
1.1 前序遍历
(a) 递归实现
public List<Integer> preorderTraversal(TreeNode root) {
ArrayList<Integer> result = new ArrayList<>();
dfs(root, result);
return result;
}
private void dfs(TreeNode root, ArrayList<Integer> result) {
if (root == null)
return;
result.add(root.val);
dfs(root.left);
dfs(root.right);
}
(b) 非递归实现
public List<Integer> preorderTraversal(TreeNode root) {
ArrayList<Integer> result = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
if (cur != null) {
result.add(cur.val);
stack.push(cur);
cur = cur.left;
}
else {
cur = stack.pop();
cur = cur.right;
}
}
return result;
}
1.2 中序遍历
(a) 递归实现
public List<Integer> inorderTraversal(TreeNode root) {
ArrayList<Integer> result = new ArrayList<>();
dfs(root, result);
return result;
}
private void dfs(TreeNode root, ArrayList<Integer> result) {
if (root != null) {
dfs(root.left, result);
result.add(root.val);
dfs(root.right, result);
}
}
(b) 非递归实现
public List<Integer> inorderTraversal(TreeNode root) {
ArrayList<Integer> result = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
if (cur != null) {
stack.push(cur);
cur = cur.left;
}
else {
cur = stack.pop();
result.add(cur.val);
cur = cur.right;
}
}
return result;
}
1.3 后序遍历
(a) 递归实现
public List<Integer> postorderTraversal(TreeNode root) {
ArrayList<Integer> result = new ArrayList<>();
dfs(root, result);
return result;
}
private void dfs(TreeNode root, ArrayList<Integer> result) {
if (root == null)
return;
dfs(root.left);
dfs(root.right);
result.add(root.val);
}
(b) 非递归实现
后序遍历的非递归写法,相比于前序遍历和中序遍历,要更加困难一些。因为前序遍历和中序遍历都可以在一个循环里,分两个分支,做确定的事情即可。而后序遍历不一样,后序遍历在遇到null弹栈的时候,有两种情况,一种是从左子树回来,此时不能像中序遍历一样直接弹栈,因为根节点要留着,等把右子树也访问完毕后再输出,所以此时要直接进入右子树,待右子树都输出之后再回来的时候才能弹出根节点,因此我们要知道当前是从左子树回去还是从右子树回去。这里我们用一个集合Set来存储已经从左子树回去过的根节点,因此下次从右子树回去的时候,就知道应该输出根了。
public List<Integer> postorderTraversal(TreeNode root) {
ArrayList<Integer> result = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
Set<TreeNode> visited = new HashSet<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
if (cur != null) {
stack.push(cur);
cur = cur.left;
}
else {
TreeNode tmp = stack.peek();
if (visited.contains(tmp)) {
result.add(tmp.val);
stack.pop();
}
else {
visited.add(tmp);
cur = tmp.right;
}
}
}
return result;
}