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),非常巧妙。(也可以想象为把二叉树作为一个只有右子树的单链表来进行遍历。)
下面我们详述一下步骤:
- 在根节点进行判断,假如左子树为空,则我们可以把当前节点node加入到结果集里,同时node = node.right,向右子树进行遍历
- 当左子树不为空的时候,我们要先找到当前节点的predecessor。方法就是在当前节点的左子树里找到最右端的节点,此操作时间复杂度为O(logn)。这里要注意这个节点的值是小于我们当前节点的值node.val的。 此时我们有两种情况:
- 第一次访问这个predecessor时,此时predecessor的右子树肯定为空,我们把predecessor和当前node连接起来,predecessor.right = node,然后继续向左子树进行遍历,即node = node.left
- 否则,我们第二次访问这个predecessor,这时说明当前node的左子树已经被访问完毕了,我们可以做一个树的还原操作,即把predecessor.right重新置为null。接下来我们可以将当前node节点的值输出,然后继续向当前节点的右节点进行遍历。
- 查找前序节点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