先序遍历
递归:(无限套娃)
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<>();
preorderTraversal(root, list);
return list;
}
public void preorderTraversal(TreeNode root, List<Integer> list) {
if(root==null){
return;
}
list.add(root.val);
if(root.left!=null){
preorderTraversal(root.left, list);
}
if(root.right!=null){
preorderTraversal(root.right, list);
}
}
}
使用栈:
public List<Integer> preorderTraversal(TreeNode root) {
ArrayDeque<TreeNode> deque = new ArrayDeque<>();
ArrayList<Integer> list = new ArrayList<>();
TreeNode cur = root;
while (cur != null || !deque.isEmpty()) {
// 先遍历当前元素,然后左不为空 就一直去左节点
while (cur != null) {
list.add(cur.val);
deque.push(cur);
cur = cur.left;
}
// 左节点为空 则去遍历栈顶节点的右节点
cur = deque.pop().right;
}
return list;
}
中序遍历:
// 先将左子节点全部入栈,然后取出栈顶节点,将其值加入结果列表,将当前节点指向右子节点。重复这个过程直到栈为空。
public List<Integer> inorderTraversal(TreeNode root) {
ArrayDeque<TreeNode> deque = new ArrayDeque<>();
ArrayList<Integer> list = new ArrayList<>();
TreeNode cur = root;
while (cur != null || !deque.isEmpty()) {
while (cur != null) {
deque.push(cur);
cur = cur.left;
}
cur = deque.pop();
list.add(cur.val);
cur = cur.right;
}
return list;
}
后序遍历:
public List<Integer> postorderTraversal(TreeNode root) {
ArrayDeque<TreeNode> deque = new ArrayDeque<>();
ArrayList<Integer> list = new ArrayList<>();
TreeNode cur = root;
TreeNode pre = null;
while (cur != null || !deque.isEmpty()) {
while (cur != null) {
deque.push(cur);
cur = cur.left;
}
cur = deque.pop();
// cur.right == pre 代表右节点之前遍历过,当前节点就是该子树的根
if(cur.right == null || cur.right == pre){
list.add(cur.val);
pre = cur;
// 标识之后遍历栈顶元素,不向下遍历
cur = null;
}else {
// 保存当前节点 当前节点还未遍历
deque.push(cur);
// 遍历右节点
cur = cur.right;
}
}
return list;
}