原题链接在这里:https://leetcode.com/problems/binary-tree-inorder-traversal/#
本题与Binary Tree Preorder Traversal相呼应。可以分别采用Recursion, Iteration 和 Morris Traversal 三种方法。
Method 1: Recursion
Recursion是traversal时最容易想到,并且好写的方法。
Time O(n), Space O(logn).
AC Java:
/**
* 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> ls = new ArrayList<Integer>();
inorderTraversal(root, ls);
return ls;
}
public void inorderTraversal(TreeNode root, List<Integer> ls){
if(root == null){
return;
}
inorderTraversal(root.left, ls);
ls.add(root.val);
inorderTraversal(root.right, ls);
}
}
Method 2: Iteration + Stack
Iteration 时基本就是利用stack的特性体现出recursion的方法。压栈的顺序要注意,一直压left,知道null,再pop,移动root到pop出来的right。循环直到点为空并且stack也为空。
Time O(n), Space O(logn).
AC Java:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
//Method 2: Iteration
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> ls = new ArrayList<Integer>();
Stack<TreeNode> stk = new Stack<TreeNode>();
while(root!=null || !stk.empty()){
if(root!=null){
stk.push(root);
root = root.left;
}else{
root = stk.pop();
ls.add(root.val);
root = root.right;
}
}
return ls;
}
}
Method 3:
Morris Traversal 算法,参见了Morris Traversal这篇文章。
Time O(n), Space O(1).利用 constant space traverse。
基本思路就是:
1. 看当前点cur的left是否为null,若是null,add当前节点,cur = cur.right.
2. cur.left 不为 null,先在左子树中找到cur 的predecessor,然后分两种情况考虑:
a. predecessor.right = null,那么predecessor.right 指向 cur; cur = cur.left.
b. predecessor.right = cur, 那么先add cur,然后把predecessor.right 改回null,恢复树的结构,然后cur = cur.right.
Note: 1. while()里的条件和下面的if()条件是相呼应的. e.g while()里若写a.next != null, 下面的if()里就应该写a.next 的先关特性。
2. 代码看起来是两个while循环嵌套,感觉是Time 是O(n*logn),其实每个边最多被访问2次,edge的上限是n-1,所以Time is O(n).
AC Java:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
//Method 3: Morris Traversal
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> ls = new ArrayList<Integer>();
TreeNode cur = root;
TreeNode pre = null;
while(cur != null){
if(cur.left == null){
ls.add(cur.val);
cur = cur.right;
}
else{
//Left node is not null, find predcessor
pre = cur.left;
while(pre.right!=null && pre.right!=cur){ //error
pre = pre.right;
}
if(pre.right == null){
pre.right = cur;
cur = cur.left;
}else{
ls.add(cur.val);
pre.right = null;
cur = cur.right;
}
}
}
return ls;
}
}

本文详细介绍了二叉树中序遍历的三种方法:递归、迭代+栈和莫里斯遍历。每种方法都附有对应的Java代码实现,帮助读者理解不同遍历方式的原理及优缺点。
1186

被折叠的 条评论
为什么被折叠?



