In-order Traversal: stack/recursive/morris

  1. Binary Tree Inorder Traversal

Stack

class Solution {
    public List inorderTraversal(TreeNode root) {
        List list = new ArrayList<>();
        if(root == null) return list;
        Deque stack = new ArrayDeque<>();
        while(root != null || !stack.isEmpty()){
            while(root != null){
                stack.push(root);
                root = root.left;
            }
            root = stack.pop();
            list.add(root.val);
            root = root.right;
        }
        return list;
    }
}

Recursion

class Solution {
    public List inorderTraversal(TreeNode root) {
        List result = new ArrayList<>();
        if(root == null) return result;
        
        // method: recursion
        helper(root, result);
        return result;
    }

    private void helper(TreeNode root, List result) {
        if (root.left != null) {
            helper(root.left, result);
        }
        result.add(root.val);
        if (root.right != null) {
            helper(root.right, result);
        }
    }
}

Morris Traversal
思路: Instead of 用stack或递归 回到父结点parent,找到parent在左树中In-order遍历时的前驱结点c,将c.right=parent。这样都创建好return link好后,遍历时只需要能左就左,左没有就右即可。创建return link 是在第一次访问被return node做的,如刚开始时第一次到root,做好左树"右下"root的In-order前驱.right=root,做好这个link后向左树继续访问,(重复此过程)这样之后访问到当时"root的前驱"就可以通过.right 回到root,回到root的时候将重复此创建return link过程将return link去掉恢复成原来样子。
这样一来空间复杂度就是O(1) ,时间复杂度虽然多了找parent在左树前驱的过程,A n-node binary tree has n-1 edges,但每个edge最多还是3次(1次建立return link时,1次遍历时,1次恢复时)所以还是O(N)。
reference: http://www.cnblogs.com/AnnieKim/archive/2013/06/15/MorrisTraversal.html

class Solution {
    public List inorderTraversal(TreeNode root) {
        List res = new ArrayList();
        if(root == null) return res;
        
        TreeNode pre = null;
        while(root != null){
            if(root.left == null){
                // no need to make (root's precursor in in-order).right = root to return since there is no left
                res.add(root.val);
                root = root.right;
            }else{
                // need to make (root's precursor in in-order).right = root to return
                // find (root's precursor in in-order)
                pre = root.left;
                while(pre.right != null && pre.right != root){
                    pre = pre.right;
                }
                if(pre.right == null){
                    // (root's precursor in in-order).right = root to return 
                    pre.right = root;
                    root = root.left;
                }else{
                    // if already Morris-linked, remove it to make it restored
                    pre.right = null;
                    res.add(root.val);
                    root = root.right;
                }
            }
        }
        return res;
    }
}
  1. Kth Smallest Element in a BST
 public int kthSmallest(TreeNode root, int k) {
     Deque stack = new ArrayDeque<>();
     while(root != null || !stack.isEmpty()) {
         while(root != null) {
             stack.push(root);    
             root = root.left;   
         } 
         root = stack.pop();
         if(--k == 0) break;
         root = root.right;
     }
     return root.val;
 }
  1. Validate Binary Search Tree
class Solution {
    public boolean isValidBST(TreeNode root) {
        if (root == null) return true;
        Deque stack = new ArrayDeque<>();
        TreeNode pre = null;
        while (root != null || !stack.isEmpty()) {
            while (root != null) {
                stack.push(root);
                root = root.left;
            }
            root = stack.pop();
            if(pre != null && root.val <= pre.val) return false;
            pre = root;
            root = root.right;
        }
        return true;
    }
}
  1. Kth Smallest Element in a BST
    Stack写法
class Solution {
    public int kthSmallest(TreeNode root, int k) {
        int count = k;
        TreeNode cur = root;
        Deque stack = new ArrayDeque<>();
        while(cur != null || !stack.isEmpty()){
            while(cur != null){
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.pop();
            count--;
            if(count == 0) return cur.val;
            
            cur = cur.right;
        }
        return Integer.MIN_VALUE; //not found
    }
}

递归写法

class Solution {
    private int result;
    private int count;
    
    public int kthSmallest(TreeNode root, int k) {
        count = k;
        helper(root);
        return result;
    }
    
    public void helper(TreeNode node) {
        if(node == null) return;
        
        helper(node.left);
        count--;
        if (count == 0) {
            result = node.val;
            return;
        }
        helper(node.right);    
    }
}
  1. Minimum Absolute Difference in BST
class Solution {
    public int getMinimumDifference(TreeNode root) {
        if(root == null) return 0;
        int min_dff = Integer.MAX_VALUE;
        Deque stack = new ArrayDeque<>();
        TreeNode prev = null;
        while(root != null || !stack.isEmpty()) {
            while(root != null) {
                stack.push(root);
                root = root.left;
            }
            root = stack.pop();
            //System.out.println("prev.val: " + prev.val);
            if(prev != null)
                min_dff = Math.min(min_dff, root.val - prev.val);
            prev = root;
            root = root.right; 
        }
        return min_dff;
    }
}

递归写法:

public class Solution {
    int min = Integer.MAX_VALUE;
    Integer prev = null;
    
    public int getMinimumDifference(TreeNode root) {
        if (root == null) return min;
        getMinimumDifference(root.left);
        if (prev != null) {
            min = Math.min(min, root.val - prev);
        }
        prev = root.val;
        getMinimumDifference(root.right);
        return min;
    }
}

你可能感兴趣的:(In-order Traversal: stack/recursive/morris)