Leetcode brushing notes (12) - pre-middle-post-order traversal of the binary tree in the binary tree chapter

Series Article Directory

1. Array type problem solving method 1: Dichotomy
2. Array type problem solving method 2: Double pointer method
3. Array type problem solving method 3: Sliding window
4. Array type problem solving method 4: Simulation
5. Linked list in linked list Basic operations and classic topics
of 6. The classic topic of the hash table chapter
7. The classic topic of the string chapter
8. The KMP of the string chapter
9. Problem solving method: double pointer
10. The classic topic of the stack and queue chapter
11. The top-K question of stack and queue is being
updated ...


foreword

The route of brushing questions comes from: Code Caprice

Binary tree:

public class TreeNode {
    
    
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode() {
    
    }
    TreeNode(int val) {
    
     this.val = val; }
    TreeNode(int val, TreeNode left, TreeNode right) {
    
    
        this.val = val;
        this.left = left;
       this.right = right;
    }
}

The pre-middle-post-order traversal of a binary tree means that the front-middle-post traversal actually refers to the traversal order of the intermediate nodes.

Bibliographic

144. Preorder Traversal of Binary Trees

Given the root node root of a binary tree, return a preorder traversal of its node values.
Leetcode link
problem solution:
Method 1: Recursive method

class Solution {
    
    
    public List<Integer> preorderTraversal(TreeNode root) {
    
    
        List<Integer> list = new ArrayList<>();
        preorder(root, list);
        return list;
    }
    public void preorder(TreeNode root, List<Integer> list) {
    
    
    	// 结束条件
        if (root == null) return;
        // 中 -> 左 -> 右
        list.add(root.val);
        preorder(root.left, list);
        preorder(root.right, list);
    }
}

Method 2: Iterative method 1

class Solution {
    
    
    public List<Integer> preorderTraversal(TreeNode root) {
    
    
        List<Integer> res = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        // 先把根结点添加到栈中
        if (root != null) stack.push(root);
        while (!stack.isEmpty()) {
    
    
        	// 弹出栈顶元素,并添加到返回值中
            TreeNode node = stack.pop();
            res.add(node.val);
            // 右孩子 -> 左孩子 顺序入栈,弹出栈顶元素的顺序就是: 左孩子 -> 右孩子
            if (node.right != null) stack.push(node.right);
            if (node.left != null) stack.push(node.left);
        }
        return res;
    }
}

Method 2: Iterative method 2

class Solution {
    
    
    public List<Integer> preorderTraversal(TreeNode root) {
    
    
        List<Integer> res = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        // cur 用来遍历二叉树
        TreeNode cur = root;
        while (cur != null || !stack.isEmpty()) {
    
    
            if (cur != null) {
    
    
            	// cur 不为空,添加结点 val 值到返回 List 中,并入栈保存遍历路径,然后 cur 向左走
                res.add(cur.val);
                stack.push(cur);
                cur = cur.left;
            } else {
    
    
            	// cur 向左走到头了,弹出栈顶结点,然后 cur 向右走
                cur = stack.pop();
                cur = cur.right;
            }
        }
        return res;
    }
}

94. Inorder Traversal of Binary Trees

Given a root node root of a binary tree, return its in-order traversal.
Leetcode link
problem solution:
Method 1: Recursive method

class Solution {
    
    
    public List<Integer> inorderTraversal(TreeNode root) {
    
    
        List<Integer> res = new ArrayList<>();
        inorder(root, res);
        return res;
    }
    public void inorder(TreeNode root, List<Integer> res) {
    
    
        if (root == null) return;
        // 左 ->  中 -> 右
        inorder(root.left, res);
        res.add(root.val);
        inorder(root.right, res);
    }
}

Method 2: Iterative method

class Solution {
    
    
    public List<Integer> inorderTraversal(TreeNode root) {
    
    
        List<Integer> res = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        // cur 用来遍历二叉树
        TreeNode cur = root;
        while (cur != null || !stack.isEmpty()) {
    
    
            if (cur != null) {
    
    
            	// cur 不为空,结点入栈,cur 向左走
                stack.push(cur);
                cur = cur.left;
            } else {
    
    
            	// 向左走到头了,弹出栈顶元素,添加 val 值到 list 中,cur 向右走
                cur = stack.pop();
                res.add(cur.val);
                cur = cur.right;
            }
        }
        return res;
    }
}

145. Postorder Traversal of Binary Trees

Given the root node root of a binary tree, return a postorder traversal of its node values.
Leetcode link
problem solution:
Method 1: Recursive method

class Solution {
    
    
    public List<Integer> postorderTraversal(TreeNode root) {
    
    
        List<Integer> res = new ArrayList<>();
        postorder(root, res);
        return res;
    }
    public void postorder(TreeNode root, List<Integer> res) {
    
    
        if (root == null) return;
        // 左 -> 右 -> 中 
        postorder(root.left, res);
        postorder(root.right, res);
        res.add(root.val);
    }
}

Method 2: Iterative
method 1 with pre-order traversal, because the order of post-order traversal is left -> right -> middle, if you look at it in reverse, it is middle -> right -> left, just change the pre-order traversal The left and right children of iteration method 1 are put into the stack, traversed in the order of middle -> right -> left, and finally reversed and returned to the List

class Solution {
    
    
    public List<Integer> postorderTraversal(TreeNode root) {
    
    
        List<Integer> res = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while (!stack.isEmpty()) {
    
    
        	// 出栈时添加 val 值到返回 list 中
            TreeNode node = stack.pop();
            res.add(node.val);
            // 入栈顺序:左 -> 右,出栈顺序:右 -> 左
            if(node.left != null) stack.push(node.left);
            if(node.right != null) stack.push(node.right);
        }
        // 反转 list
        Collections.reverse(res);
        return res;
    }
}

Method 3: Iteration method 2
Because the parent node is traversed at the end in the local, when traversing the right subtree, the parent node needs to be popped up first as above . At this time, the val value cannot be added to the return list, because the right subtree has not been Traversing, you need to add the popped node to the stack again .
Only when the right subtree has been traversed or there is no right subtree can val be added to the return value, so how do you know that the right subtree has been traversed, then you need a prev pointer to record the last traversed node

class Solution {
    
    
    public List<Integer> postorderTraversal(TreeNode root) {
    
    
        List<Integer> res = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        // cur 用来遍历
        TreeNode cur = root;
        // prev 用来记录上次遍历的个结点
        TreeNode prev = null;
        while (cur != null || !stack.isEmpty()) {
    
    
            if (cur != null) {
    
    
                stack.add(cur);
                cur = cur.left;
            } else {
    
    
                cur = stack.pop();
                if (cur.right != null && cur.right != prev) {
    
    
                    // 有右子树并且右子树没遍历,需放回根结点到栈中
                    stack.push(cur);
                    // 接下来遍历右子树
                    cur = cur.right;
                } else {
    
    
                    // 没有右子树,或者右子树被遍历过,
                    res.add(cur.val);
                    // 更新前指针
                    prev = cur;
                    // 以该结点的子树都已遍历,下次需要从栈中取父亲结点向上遍历,所以 cur == null
                    cur = null;
                }
            }
        }
        return res;
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325238604&siteId=291194637