前序遍历
- 处理当前节点
- 一直向下搜索左子树
- 当前节点左子树为空了,切换到当前节点右子树重复上述步骤
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new LinkedList();
Deque<TreeNode> stack = new ArrayDeque();
if (root == null)
return res;
while (!stack.isEmpty() || root != null) {
if (root != null) {
// 处理当前节点
res.add(root.val);
stack.push(root);
// 一直向下搜索左子树
root = root.left;
} else {
// 左子树没了, 切换到右子树
TreeNode top = stack.pop();
root = top.right;
}
}
return res;
}
后序遍历
前序遍历为:中左右;后序遍历为左右中。
- 处理当前节点
- 前序遍历是先一直向下搜索左子树,那么后序先一直向下搜索右子树
- 前序遍历是左子树空了切换到右子树,那么后序右子树空了切换到左子树
- 最后将
res
反转
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new LinkedList();
if (root == null) {
return res;
}
TreeNode poppedNode = null;
Deque<TreeNode> stack = new ArrayDeque<TreeNode>();
while (!stack.isEmpty() || root != null) {
if (root != null) {
// 处理当前节点
res.add(root.val);
// 一直向下左子树
stack.push(root);
root = root.right;
} else {
// 左子树没了,遍历右子树
TreeNode top = stack.pop();
root = top.left;
}
}
Collections.reverse(res);
return res;
}
中序遍历
- 一直向下搜索左子树
- 当前节点左子树空了,处理当前节点
- 切换到当前的右子树,重复上述过程
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new LinkedList();
Deque<TreeNode> stack = new ArrayDeque();
while (!stack.isEmpty() || root != null) {
// 一直向下搜索左子树
while (root != null) {
stack.push(root);
root = root.left;
}
// 左子树空了,处理当前节点
TreeNode top = stack.pop();
res.add(top.val);
// 切换到右子树
root = top.right;
}
return res;
}
总结
模版大概就这样
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new LinkedList();
Deque<TreeNode> stack = new ArrayDeque();
while (!stack.isEmpty() || root != null) {
if (root != null) {
....
} else {
...
}
}
...
return res;
}