[Likou brush question] Day14 - Binary tree topic


Introduction to Binary Trees

Many concepts can be seen in previous blogs: Binary tree traversal_Tatakai!!!'s blog-CSDN blog_Binary tree traversal

Binary tree traversal

  • Preorder traversal: around the root
  • Inorder traversal: left root right
  • Post-order traversal: left and right roots
  • Layer order traversal: BFS

Method to realize:

  • recursion
  • non-recursive (stack)

1. Recursive implementation

preorder traversal

Code

class Solution {
    
    
    public List<Integer> preorderTraversal(TreeNode root) {
    
    
        List<Integer> res = new ArrayList<>();
        dfs(root, res);
        return res;
    }
    /**
        前:根左右
     */
    public static void dfs(TreeNode root, List<Integer> res){
    
    
        if(root == null){
    
    // 叶子节点
            return ;
        }
        res.add(root.val);
        dfs(root.left, res);
        dfs(root.right, res);

    }
}

Inorder traversal

Code

class Solution {
    
    
     List<Integer> ans = new ArrayList<>();
    public List<Integer> inorderTraversal(TreeNode root) {
    
    
        dfs(root);
        return ans;
    }
    // 中序遍历
    public void dfs(TreeNode root){
    
    
        // 结束条件
        if(root == null) return;
        dfs(root.left);
        ans.add(root.val);
        dfs(root.right);
    }
}

post order traversal

Code

class Solution {
    
    
    public List<Integer> postorderTraversal(TreeNode root) {
    
    
        List<Integer> res = new ArrayList<>();
        dfs(root, res);
        return res;
    }
    /**
        后:左右根
     */
    public static void dfs(TreeNode root, List<Integer> res){
    
    
        if(root == null){
    
    // 叶子节点
            return ;
        }
        dfs(root.left, res);
        dfs(root.right, res);
        res.add(root.val);

    }
}

2. Iterative implementation

preorder traversal

Idea: Use the stack to simulate the pre-order traversal process, because it is a stack (first in, last out)

  • Root node first stack
  • When the stack is not empty, the right child is pushed into the stack first, and then the left child is pushed into the stack (last in, first out)

Stack simulation: root left-right -> root right-left

Code

class Solution {
    
    
    public List<Integer> preorderTraversal(TreeNode root) {
    
    
        List<Integer> res = new ArrayList<>();
        if(root == null){
    
    
            return res;
        }

        // 前:根左右
        Stack<TreeNode> stk = new Stack<>();
        stk.push(root);
        while(!stk.empty()){
    
    
            TreeNode node = stk.pop();
            res.add(node.val);

            // 右儿子先入栈
            if(node.right != null){
    
    
                stk.push(node.right);
            }
            // 做儿子入队
            if(node.left != null){
    
    
                stk.push(node.left);
            }
        }
        return res;
    }
}

post order traversal

The above iterative method obtains the pre-order traversal: 根左右—> The iterative process 根右左traverses and inserts in the order of , and finally obtains the result of the pre-order traversal ( 根左右)

And the post-order traversal is 左右根, its flip is 根右左, then we only need to find a way to get 根左右the order of this tree, and then flip it to get the result of the subsequent traversal! , so 根右左how do we get the result of the traversal order? ——Imitate the acquisition process of the preorder traversal iteration:

  • 根左右—> 根右左Obtained by the stacking order
  • Then 根右左—> 根左Obtained by the order of stacking

Code

/**
 * Definition for a binary tree node.
 * 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;
 *     }
 * }
 */
class Solution {
    
    
    public List<Integer> postorderTraversal(TreeNode root) {
    
    
        List<Integer> list = new ArrayList<>();
        if(root == null){
    
    
            return list;
        }

        Stack<TreeNode> stk = new Stack<>();
        stk.push(root);
        // 先获取根右左的遍历次序结果
        while(!stk.empty()){
    
    
            TreeNode node = stk.pop();
            list.add(node.val);

            if(node.left != null){
    
    
                stk.push(node.left);
            }
            if(node.right != null){
    
    
                stk.push(node.right);
            }
        }
        // 翻转得到后序遍历结果
        Collections.reverse(list);
        return list;

    }
}

Inorder traversal

middle:左根右

Iterative method:

  • Define a pointer to the root node, and keep looping when the node is not empty or the stack is not empty

    • When the pointer is not empty , the current node is pushed onto the stack , and the left son has been looped through , and so on until it p指针points to empty ------- (simulation 左递归of the process)
    • When the pointer is empty , the top element of the stack is popped out, the pointer points to the node popped out of the stack, and p = stk.pop()the node value valis added ans(simulating the process of traversing the root, recording the answer), and then the pointer pmoves to the right son of the current node (simulating the right child of the traversal process), prepare for the next time (left root right)
  • And so on, until the stack is empty.

Code

class Solution {
    
    
    public List<Integer> inorderTraversal(TreeNode root) {
    
    
        TreeNode p = root;
        Stack<TreeNode> stk = new Stack<>();
        List<Integer> ans = new ArrayList<>();

        while(p != null || !stk.empty()){
    
    
            while(p != null){
    
    // 模拟一直左递归的过程
                stk.push(p);
                p = p.left;
            }
            // p走到了空
            // 根
            p = stk.pop();
            ans.add(p.val);
            
            // 右
            p = p.right;
        }
        return ans;
    }
}

Guess you like

Origin blog.csdn.net/qq_54773252/article/details/127170789