94. Binary Tree Inorder Traversal (Easy)
遍历树的方法通常有三种,分别是前序遍历 pre-order traversal、中序遍历 in-order traversal 和后序遍历 post-order traversal。这道题是中序遍历。
难度上来说,前序最简单,中序和后序遍历会复杂一点。
思路 1,递归
class Solution: |
思路 2,遍历
基于前序遍历的方案做的修改,可以解决问题,但是在空间复杂度上有优化余地,为了储存 stack 使用了额外的 2n 的空间。
class Solution: |
思路 3,遍历,优化版本
中序遍历要先遍历左节点,所以先抵达最左路径的最后一个节点,从这个节点开始回溯,重复检查左节点,本体和右节点的顺序。
这其实是思路 1 递归的扁平化处理,使用 stack 来替代递归过程。时间复杂度和空间复杂度均为 O(n)。
class Solution: |
思路 4,莫里斯遍历 Morris Traversal
也叫线索二叉树(Threaded Binary Tree),修改树的结构,让其“穿起来”成为一条线,整个遍历过程重复修改结构 -> 遍历数据的过程。
具体做法如下:
- 当前节点不存在左节点时
- 记录当前节点值
- 将右节点标记为当前节点
- 当前节点存在左节点时
- 将当前节点挂在左节点的最后一个右节点上
- 将左节点标记为当前节点
- 重复这个过程直到不存在当前节点
class Solution: |
抄一个 Threaded Binary Tree 的解释方便理解。
For example:
1
/ \
2 3
/ \ /
4 5 6First, 1 is the root, so initialize 1 as current, 1 has left child which is 2, the current’s left subtree is
2
/ \
4 5So in this subtree, the rightmost node is 5, then make the current(1) as the right child of 5. Set current = cuurent.left (current = 2). The tree now looks like:
2
/ \
4 5
\
1
\
3
/
6For current 2, which has left child 4, we can continue with thesame process as we did above
4
\
2
\
5
\
1
\
3
/
6then add 4 because it has no left child, then add 2, 5, 1, 3 one by one, for node 3 which has left child 6, do the same as above. Finally, the inorder traversal is [4,2,5,1,6,3].