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].

链接: http://leetcode.com/problems/binary-tree-inorder-traversal/

题解:

二叉树中序遍历。 

Iterative:         

Time Complexity - O(n), Space Complexity - O(n) (worst case)

public class Solution {
    public ArrayList<Integer> inorderTraversal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList<Integer>();
        if(root == null)
            return result;
        Stack<TreeNode> stack = new Stack<TreeNode>();
        
        while(root != null || !stack.isEmpty()){
            if(root != null){
                stack.push(root);
                root = root.left;
            } else {
                root = stack.pop();
                result.add(root.val);
                root = root.right;
            }
        }
        
        return result;
    }
}

 

Recursive:

Time Complexity - O(n), Space Complexity - O(n) (worst case)

public class Solution {
    public ArrayList<Integer> inorderTraversal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList<Integer>();
        inorderTraversal(root, result);
        return result;
    }
    
    private void inorderTraversal(TreeNode root, ArrayList<Integer> result){
        if(root == null)
            return;
        inorderTraversal(root.left, result);
        result.add(root.val);
        inorderTraversal(root.right, result);
    }
}

 

Morris Travel: (待完成)

 

二刷:

Java:

Iterative:

Time Complexity - O(n), Space Complexity - O(n) (worst case)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if (root == null) {
            return res;
        }
        LinkedList<TreeNode> list = new LinkedList<>();
        while (root != null || list.size() > 0) {
            if (root != null) {
                list.addLast(root);
                root = root.left;
            } else {
                root = list.pollLast();
                res.add(root.val);
                root = root.right;
            }
        }
        return res;
    }
}

 

Recursive:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        inorderTraversal(res, root);
        return res;
    }
    
    private void inorderTraversal(List<Integer> res, TreeNode root) {
        if (root == null) {
            return;
        }
        inorderTraversal(res, root.left);
        res.add(root.val);
        inorderTraversal(res, root.right);
    }
}

 

三刷:

Java:

 

Iterative using a stack

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        TreeNode node = root;
        while (node != null || !stack.isEmpty()) {
            if (node != null) {
                stack.push(node);
                node = node.left;
            } else {
                node = stack.pop();
                res.add(node.val);
                node = node.right;
            }
        }
        return res;
    }
}

 

 

 

Recursive: 

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        inorderTraversal(res, root);
        return res;
    }
    
    private void inorderTraversal(List<Integer> res, TreeNode root) {
        if (root == null) return;
        inorderTraversal(res, root.left);
        res.add(root.val);
        inorderTraversal(res, root.right);
    }
}

 

Morris Traversal:

在可以改变树结构的情况下,主要使用空的右节点来保存一个通向当前节点的link,二次遍历,在第二次遍历的时候还原树。这样做我们可以达到O(1)的空间复杂度,而时间复杂度仍然能保持O(n),非常巧妙。(也可以想象为把二叉树作为一个只有右子树的单链表来进行遍历。)

下面我们详述一下步骤:

  1. 在根节点进行判断,假如左子树为空,则我们可以把当前节点node加入到结果集里,同时node = node.right,向右子树进行遍历
  2. 当左子树不为空的时候,我们要先找到当前节点的predecessor。方法就是在当前节点的左子树里找到最右端的节点,此操作时间复杂度为O(logn)。这里要注意这个节点的值是小于我们当前节点的值node.val的。 此时我们有两种情况:
    1. 第一次访问这个predecessor时,此时predecessor的右子树肯定为空,我们把predecessor和当前node连接起来,predecessor.right = node,然后继续向左子树进行遍历,即node = node.left
    2. 否则,我们第二次访问这个predecessor,这时说明当前node的左子树已经被访问完毕了,我们可以做一个树的还原操作,即把predecessor.right重新置为null。接下来我们可以将当前node节点的值输出,然后继续向当前节点的右节点进行遍历。
  3. 查找前序节点predecessor的操作是O(logn),但进行平滩分析的话,在这个环节我们每个节点也只被访问两次 - 一次修改,一次还原。所以总的来说还是O(n)

Time Complexity - O(n), Space Complexity - O(1) 

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        TreeNode node = root, prev = null;
        while (node != null) {
            if (node.left == null) {
                res.add(node.val);
                node = node.right;
            } else {
                prev = node.left;
                while (prev.right != null && prev.right != node) {
                    prev = prev.right;
                }
                if (prev.right == node) {
                    prev.right = null;
                    res.add(node.val);
                    node = node.right;
                } else {
                    prev.right = node;
                    node = node.left;
                }
            }
        }
        return res;
    }
}

 

 

测试:

Reference:

http://noalgo.info/832.html

http://www.cnblogs.com/AnnieKim/archive/2013/06/15/morristraversal.html

http://blog.codinghonor.com/2014/11/26/morris-traversal/

http://www.geekviewpoint.com/java/bst/morris_in_order

posted @ 2015-04-18 12:16  YRB  阅读(530)  评论(0编辑  收藏  举报