二叉树遍历小结
声明
0 二叉树遍历概述
二叉树遍历:按照既定序,对每个节点仅访问一次;
二叉树非递归遍历思想:参考这篇博文,核心思想是存在重合元素的局部有序保证整体有序,由于二叉树的结构特点,二叉树中的每个节点(除根节点和叶子节点)均属于两个局部的重合元素。对于任一重合元素,保证所在两个局部遍历有序,保证实现整体遍历有序;
重合元素所在局部:
局部全部有序,遍历该元素并出栈;
局部未全部有序,将未有序局部元素全部入栈。由于栈是LIFO,局部元素按照逆序入栈;
二叉树节点TreeNode声明
public class TreeNode {
public int val;
public TreeNode left, right;
public TreeNode(int val) {
this.val = val;
this.left = this.right = null;
}
}
1 前序遍历
1.1 非递归实现
public class Solution {
private class Pair {
public TreeNode node;
public boolean isVisited;
public Pair(TreeNode node, boolean isVisited) {
this.node = node;
this.isVisited = isVisited;
}
}
public ArrayList preorderTraversal(TreeNode root) {
ArrayList list = new ArrayList();
if (root == null) {
return list;
}
ArrayDeque stack = new ArrayDeque();
stack.push(new Pair(root, false));
while (!stack.isEmpty()) {
Pair top = stack.pop();
// 重合节点完成所有局部有序,弹出
if (top.isVisited) {
list.add(top.node.val);
} else {
// reverse: right -> left -> root
if (top.node.right != null) {
stack.push(new Pair(top.node.right, false));
}
if (top.node.left != null) {
stack.push(new Pair(top.node.left, false));
}
stack.push(new Pair(top.node, true));
}
}
return list;
}
}
1.2 递归实现
public class Solution {
public ArrayList preorderTraversal(TreeNode root) {
ArrayList list = new ArrayList();
if (root == null) {
return list;
}
traverse(list, root);
return list;
}
private void traverse(ArrayListlist, TreeNode root) {
if (root == null) {
return;
}
list.add(root.val);
traverse(list, root.left);
traverse(list, root.right);
}
}
2 中序遍历
2.1 非递归实现
public class Solution {
private class Pair {
public TreeNode node;
public boolean isVisited;
public Pair(TreeNode node, boolean isVisited) {
this.node = node;
this.isVisited = isVisited;
}
}
public ArrayList inorderTraversal(TreeNode root) {
ArrayList list = new ArrayList();
if (root == null) {
return list;
}
ArrayDeque stack = new ArrayDeque();
stack.push(new Pair(root, false));
while (!stack.isEmpty()) {
Pair top = stack.pop();
if (top.isVisited) {
list.add(top.node.val);
} else {
// reverse: right -> root -> left
if (top.node.right != null) {
stack.push(new Pair(top.node.right, false));
}
stack.push(new Pair(top.node, true));
if (top.node.left != null) {
stack.push(new Pair(top.node.left, false));
}
}
}
return list;
}
}
2.2 递归实现
public class Solution {
public ArrayList inorderTraversal(TreeNode root) {
ArrayList list = new ArrayList();
if (root == null) {
return list;
}
traverse(list, root);
return list;
}
private void traverse(ArrayListlist, TreeNode root) {
if (root == null) {
return;
}
traverse(list, root.left);
list.add(root.val);
traverse(list, root.right);
}
}
3 后序遍历
3.1 非递归实现
public class Solution {
private class Pair {
public TreeNode node;
public boolean isVisited;
public Pair(TreeNode node, boolean isVisited) {
this.node = node;
this.isVisited = isVisited;
}
}
public ArrayList postorderTraversal(TreeNode root) {
ArrayList list = new ArrayList();
if (root == null) {
return list;
}
ArrayDeque stack = new ArrayDeque();
stack.push(new Pair(root, false));
while (!stack.isEmpty()) {
Pair top = stack.pop();
if (top.isVisited) {
list.add(top.node.val);
} else {
// reverse: root -> right -> left
stack.push(new Pair(top.node, true));
if (top.node.right != null) {
stack.push(new Pair(top.node.right, false));
}
if (top.node.left != null) {
stack.push(new Pair(top.node.left, false));
}
}
}
return list;
}
}
3.2 递归实现
public class Solution {
public ArrayList postorderTraversal(TreeNode root) {
ArrayList list = new ArrayList();
if (root == null) {
return list;
}
traverse(list, root);
return list;
}
private void traverse(ArrayList list, TreeNode root) {
if (root == null) {
return;
}
traverse(list, root.left);
traverse(list, root.right);
list.add(root.val);
}
}
4 层序遍历
public class Solution {
public ArrayList> levelOrder(TreeNode root) {
ArrayDeque queue = new ArrayDeque();
ArrayList> list = new ArrayList>();
if (root == null) {
return list;
}
queue.offer(root);
while (!queue.isEmpty()) {
int level = queue.size();
ArrayList levelList = new ArrayList();
// 按层BFS遍历
for (int i = 0; i < level; i++) {
TreeNode head = queue.poll();
levelList.add(head.val);
if (head.left != null) {
queue.offer(head.left);
}
if (head.right != null) {
queue.offer(head.right);
}
}
list.add(levelList);
}
return list;
}
}