前序遍历, 中序遍历和后序遍历过程: 遍历过程中经过结点的路线一样, 只是访问各结点时机不同
前序遍历
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> ans = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
while (! stack.isEmpty() || root != null) {
// 就像递归算法的preorder(root.left),不断的往左边走,直到root为null返回
// 因为是前序遍历,所以第一次遇到就访问
while (root != null) {
stack.push(root);
ans.add(root.val);
root = root.left;
}
// 转为右子树方向
if (! stack.isEmpty()) {
root = stack.pop();
root = root.right;
}
}
return ans;
}
}
中序遍历,只是改变了访问结点的时机
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<TreeNode>();
while (! stack.isEmpty() || root != null) {
while (root != null) {
stack.push(root);
root = root.left;
}
if (! stack.isEmpty()) {
root = stack.pop();
list.add(root.val);
root = root.right;
}
}
return list;
}
}
后序遍历
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode node = null;
while (! stack.isEmpty() || root != null) {
while (root != null) {
stack.push(root);
root = root.left;
}
if (! stack.isEmpty()) {
root = stack.pop();
// 如果 root 没有右孩子 或者 右孩子已经遍历过了
if (root.right == null || root.right == node) {
list.add(root.val);
node = root;
root = null; // 这一步很重要,否则会重复遍历
}
else {
stack.push(root);
root = root.right;
}
}
}
return list;
}
}
层序遍历
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
if (root == null) {
return new ArrayList<List<Integer>>();
}
List<List<Integer>> list = new ArrayList<>();
ArrayDeque<TreeNode> queue = new ArrayDeque<>();
queue.add(root);
while (! queue.isEmpty()) {
List<Integer> list1 = new ArrayList<>();
int n = queue.size(); // 表示上一层有多少个结点,这样就可以一层一层的遍历
for (int i = 0; i < n; i++) {
root = queue.poll();
list1.add(root.val);
if (root.left != null) {
queue.add(root.left);
}
if (root.right != null) {
queue.add(root.right);
}
}
list.add(list1);
}
return list;
}
}