题目:二叉树的中序遍历
给定一个二叉树,返回它的中序遍历。
示例:
输入: [1,null,2,3]
1
\
2
/
3
输出: [1,3,2]
- 进阶: 递归算法很简单,你可以通过迭代算法完成吗?
来源:力扣(LeetCode)第94题
链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal
分析:
两种方法,一种是最常用的递归遍历,非常简单。第二种是迭代遍历,需要用到栈。本文章分析第二种算法。
思路:
维护一个栈,每次经过一个节点,就入栈,当节点的左节点没有值时出栈,并继续从出栈的那个节点找它的右节点。
- 维护一个栈stack和要储存答案的列表ans
- 写一个循环,不停地将左节点一层一层的入栈
- 当左节点为None时,不要入栈,并且将栈顶节点弹出
- 拿到栈顶节点的value,并且进入该节点的右节点(因为中序遍历是左,中,右)
- 继续拿这个节点的左节点,重复2-4步
- 当节点值为None 或者 stack为空时结束循环
代码:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
stack = []
ans = []
tail = root
while tail is not None or stack:
while tail is not None:
stack.append(tail)
tail = tail.left
tail = stack.pop()
ans.append(tail.val)
tail = tail.right
return ans
顺便把递归遍历的代码一起放上来
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
if root is None:
return []
stack = []
self.recursion(stack, root)
return stack
def recursion(self, stack: List[int], root: TreeNode) -> None:
if root.left != None:
self.recursion(stack, root.left)
stack.append(root.val)
if root.right != None:
self.recursion(stack, root.right)
复杂度分析:
- 递归法
- 时间复杂度: O(n) (递归函数 T(n)=2⋅T(n/2) + 1)
- 空间复杂度: O(logn)
- 迭代法
- 时间复杂度: O(n)
- 空间复杂度: O(n)
总体来说,迭代法比递归法速度更快,毕竟递归调用很耗时,而递归法节省的空间更多,适合资源不多时使用。
LeetCode上还有一种方法叫做莫里斯遍历,复杂度与迭代法一样,没仔细看过。在这里放上链接 > https://leetcode-cn.com/problems/binary-tree-inorder-traversal/solution/er-cha-shu-de-zhong-xu-bian-li-by-leetcode/
总结:
中序遍历的两种方法各有各的优点,尤其是迭代法,时间用的更少,就是实现上没有递归法那么方便。要注意通过栈来储存每次进过的节点,不然的话你再想找之前的节点就找不到了。。