Question

Formatted question description: https://leetcode.ca/all/94.html

94. Binary Tree Inorder Traversal

Given a binary tree, return the inorder traversal of its nodes' values.

For example:
Given binary tree {1,#,2,3},
   1
    \
     2
    /
   3
return [1,3,2].

Note: Recursive solution is trivial, could you do it iteratively?

@tag-tree

Algorithm

Using stack

The iterative solution using the stack is also one of the solutions that meet the requirements of this question. It needs to be done with a stack.

The idea is to start from the root node, first push the root node into the stack, and then push all its left child nodes into the stack, then take out the top node of the stack, save the node value, and then move the current pointer to its right child node. If there is a right child node, all the left child nodes can be pushed onto the stack in the next cycle. This ensures that the access sequence is left-root-right.

No stack

Neither recursion nor stack can be used, so how to ensure that the access sequence is the left-root-right of the in-order traversal. It turns out that a binary tree of clues needs to be constructed, and all the empty right child nodes need to be pointed to the next node traversed by the in-order, so that after the in-order traverses the left child node, it can smoothly return to its root node and continue the traversal.

The specific algorithm is as follows:

1 . Initialize the pointer cur to point to root

2 . When cur is not empty

 * if cur has no left child node

 * a) Print out the value of cur

 * b) Point the cur pointer to its right child node
  • on the contrary, has left child node. Point the pre pointer to the rightmost child node in the left subtree of cur  

    * If pre does not have a right child node

    * a) Point its right child node back to cur

    * b) cur points to its left child node

  * on the contrary

      * a) Empty the right child node of pre

      * b) Print the value of cur

      * c) Point the cur pointer to its right child node

Code

Java

  • import java.util.ArrayList;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Stack;
    
    public class Binary_Tree_Inorder_Traversal {
    
    	/**
    	 * Definition for a binary tree node.
    	 * public class TreeNode {
    	 *     int val;
    	 *     TreeNode left;
    	 *     TreeNode right;
    	 *     TreeNode(int x) { val = x; }
    	 * }
    	 */
    
        class Solution_noStack {
            public List<Integer> inorderTraversal(TreeNode root) {
    
                List<Integer> result = new ArrayList<>();
                TreeNode current = root;
                TreeNode prev;
    
                while (current != null) {
                    if (current.left == null) {
                        result.add(current.val);
    
                        // only handle right child
                        current = current.right; // move to next right node
                    } else { // has a left subtree
                        prev = current.left;
                        while (prev.right != null) { // find rightmost
                            prev = prev.right;
                        }
                        prev.right = current; // put cur after the pre node
                        TreeNode temp = current; // store cur node
                        current = current.left; // move cur to the top of the new tree
                        temp.left = null; // original cur left be null, avoid infinite loops
                    }
                }
    
                return result;
            }
        }
    
        public class Solution_optmize {
            public List<Integer> inorderTraversal(TreeNode root) {
    
                List<Integer> list = new ArrayList<Integer>();
                if (root == null) {
                    return list;
                }
    
                Stack<TreeNode> sk = new Stack<>();
                TreeNode current = root;
    
                while (!sk.isEmpty() || current != null) {
    
                    while (current != null) {
                        sk.push(current);
                        current = current.left;
                    } // @note: 一逼撸到最左边
    
                    // @note: 没有push left的操作,就不会无限循环,也不需要mark是否visited
                    TreeNode leftOrMiddle = sk.pop();
                    list.add(leftOrMiddle.val);
    
                    current = leftOrMiddle.right; // if right is null here, next time pop parent node
                }
    
                return list;
            }
        }
    
    
        public class Solution {
    
            List<Integer> list = new ArrayList<Integer>();
    
            public List<Integer> inorderTraversal(TreeNode root) {
    
                // mark if a node is visited already: true is visited. or, just use a Set
                HashSet<TreeNode> hs = new HashSet<>();
    
                Stack<TreeNode> sk = new Stack<>();
                sk.push(root);
    
                while (!sk.isEmpty()) {
    
                    TreeNode current = sk.pop();
    
                    if (current == null) {
                        continue;
                    }
    
                    // @note: careful to check left visited, or else infinite looping
                    if (current.left != null && !hs.contains(current.left)) {
                        sk.push(current);
                        sk.push(current.left);
    
                    } else {
    
                        if (current.right != null && !hs.contains(current.right)) {
                            sk.push(current.right);
                        }
    
                        hs.add(current);
                        list.add(current.val);
                    }
                }
    
                return list;
            }
        }
    
        class Solution_recursion {
    
            List<Integer> result = new ArrayList<>();
    
            public List<Integer> inorderTraversal(TreeNode root) {
                dfs(root);
                return result;
            }
    
            public void dfs(TreeNode root) {
                if (root == null) {
                    return;
                }
    
                dfs(root.left);
                result.add(root.val);
                dfs(root.right);
            }
        }
    }
    
  • // OJ: https://leetcode.com/problems/binary-tree-inorder-traversal/
    // Time: O(N)
    // Space: O(H)
    class Solution {
    private:
        vector<int> ans;
        void dfs(TreeNode* root) {
            if (!root) return;
            dfs(root->left);
            ans.push_back(root->val);
            dfs(root->right);
        }
    public:
        vector<int> inorderTraversal(TreeNode* root) {
            dfs(root);
            return ans;
        }
    };
    
  • # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution(object):
      def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res, stack = [], [(1, root)]
        while stack:
          p = stack.pop()
          if not p[1]: continue
          stack.extend([(1, p[1].right), (0, p[1]), (1, p[1].left)]) if p[0] != 0 else res.append(p[1].val)
        return res
    
    

All Problems

All Solutions