LeetCode questions 94, 44, 145, front, middle and back order traversal of binary trees, non-recursive

Note: The stack is used to solve the problem

1. Preorder traversal

Question requirements

Gives you the root node of the binary tree root and returns the preorder  traversal of its node value.

Example 1:

Import:root = [1,null,2,3]
Output:[1,2,3]

Example 2:

Import:root = []
Exit:[]

Example 3:

Import:root = [1]
Exit:[1]

Example 4:

Import:root = [1,2]
Output:[1,2]

Example 5:

Import:root = [1,null,2]
Output:[1,2]

Problem-solving ideas

We want to perform preorder traversal in a non-recursive way, then we can use the stack

Because the traversed values ​​must be placed in the linked list, we first store the value of the root node, and at the same time put the current node into the stack, and then traverse to the left after storing it.

Every time you traverse to the left, the value of the current root node must be put into the linked list, and the current node must also be placed on the stack.

Until roo.left == null, we have to find out whether the right subtree of the previous node is null. Because we have used the stack to store it, we can find the previous node, pop it, and get the previous node. Then determine whether the right subtree is not empty, and then keep going back through the above steps until the root node, to determine the right subtree of the root node, and then repeat the above steps.

Code display

public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        while(root != null || !stack.empty()) {
            while(root != null) {
                list.add(root.val);
                stack.push(root);
                root = root.left;
            }
            root = stack.pop();
            root = root.right;
        }
        return list;
    }

2. In-order traversal

Question requirements

Given the root node of a binary tree root , return  its  in-order < a i=4> Traverse .

Example 1:

Import:root = [1,null,2,3]
Output:[1,3,2]

Example 2:

Import:root = []
Exit:[]

Example 3:

Import:root = [1]
Exit:[1]

Problem-solving ideas

If you want to use a non-recursive idea to perform in-order traversal, the steps are actually similar to those of pre-order traversal.

As shown in the picture:

We need to first search to the left until we find the head. At the same time, every time we traverse a node, we also need to put this node into the stack.

Until the left node is empty, as shown in the figure:

Then it starts to be stored in the linked list. After storing, it returns to the previous node and also stores it in the linked list. It determines whether the right side of the node is empty. If it is empty, it will not traverse to the right. If it is not empty, it will traverse to the right. Find whether it is empty again. There is a left subtree, and the above cycle starts again

, let’s not talk about returning to the root node, it is the above cycle.

Code display:

public List<Integer> inorderTraversal(TreeNode root) {
        //非递归
        List<Integer> list = new LinkedList<>();
        Stack<TreeNode> stack = new Stack<>();

        while(root != null || !stack.empty()) {
            while(root != null) {
                stack.push(root);
                root = root.left;
            }
            root = stack.pop();
            list.add(root.val);
            root = root.right;
        }
        return list;
    }  

3. Subsequent traversal

Question requirements

Gives you the root node of a binary tree root , and returns its node value Postorder traversal  .

Example 1:

Import:root = [1,null,2,3]
Output:[3,2,1]

Example 2:

Import:root = []
Exit:[]

Example 3:

Import:root = [1]
Exit:[1]

Problem-solving ideas

The subsequent traversal is similar to the previous traversal, but because the order of the post-order traversal is the left and right roots, after we add the left node, we need to determine whether there is a right node. At this time, we cannot directly pop up the previous root node. If the previous node If there is a right node, we need to push the root node back onto the stack, and then traverse the nodes on the right. When there are no more nodes on the right, we start to save the root node into the linked list.

So we define one more node that was previously traversed to determine whether the right node has been traversed. If it has been traversed, we will directly pop this node from the stack. If it has not been traversed, we will push this node from the stack to traverse the node on the right.

Code display

public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        TreeNode prevAccess = null;
        while(root != null || !stack.empty()) {
            while(root != null) {
                stack.push(root);
                root = root.left;
            }
            root = stack.pop();
            if(root.right == null || root.right == prevAccess) {
                list.add(root.val);
                prevAccess = root;
                root = null;
            }else {
                stack.push(root);
                root = root.right;
            }
        }
        return list;
    }

Guess you like

Origin blog.csdn.net/cool_tao6/article/details/134383373