import com.freetymekiyan.algorithms.utils.Utils.TreeNode; import java.util.ArrayList; import java.util.List; import java.util.Stack; /** * Given a binary tree, return the inorder traversal of its nodes' values. * <p> * For example: * Given binary tree {1,#,2,3}, * 1 * \ * 2 * / * 3 * return [1,3,2]. * <p> * Note: Recursive solution is trivial, could you do it iteratively? * <p> * Tags: Tree, HashTable, Stack */ class BTInOrder { public static void main(String[] args) { } /** * Stack solution, O(n) Space * Use a stack to store TreeNodes * Go to left most and add each node * Pop the node from stack, add its value, and try to go right * Stop if stack is empty or node is null */ public static List<Integer> inorderTraversal(TreeNode root) { List<Integer> result = new ArrayList<Integer>(); Stack<TreeNode> s = new Stack<TreeNode>(); while (!s.isEmpty() || root != null) { // check whether current node is null if (root != null) { // current node is not null s.push(root); root = root.left; } else { // current node is null, pop and go right root = s.pop(); result.add(root.val); // visit() root = root.right; } } return result; } /** * <strong>Morris Traversal</strong> * O(1) space * Use cur for current node, pre for predecessor of cur node * Check whether left subtree exists * If yes, find rightmost node in left subtree * Check whether rightmost node is connected with cur node * If connected, break the connection and visit and move to right subtree * Otherwise, connect and traverse left subtree * If no, visit cur node and traverse right subtree */ public static List<Integer> inorderTraversalB(TreeNode root) { List<Integer> res = new ArrayList<Integer>(); if (root == null) { return res; } TreeNode cur = root; TreeNode pre = null; while (cur != null) { if (cur.left == null) { res.add(cur.val); // visit cur = cur.right; // move to right } else { pre = cur.left; while (pre.right != null && pre.right != cur) { pre = pre.right; } if (pre.right == null) { // connect with cur pre.right = cur; cur = cur.left; // traverse left subtree } else { // left subtree is done pre.right = null; res.add(cur.val); // visit cur = cur.right; // move to right } } } return res; } }