zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    oracle 11g完全彻底的卸载
    Windows添加.NET Framework 3.0 NetFx3 失败
    Crontab中的除号(slash)到底怎么用?
    Codeigniter文件上传类型不匹配错误
    Mac下遇到 'reading initial communication packet’ 问题
    使用PHP的正则抓取页面中的网址
    关于Advertising Campaign
    20个Linux服务器安全强化建议(三)
    20个Linux服务器安全强化建议(二)
    20个Linux服务器安全强化建议(一)
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4437166.html
Copyright © 2011-2022 走看看