用系统堆栈实现(递归)

很容易实现:

  1. 前序:do(), 递归左儿子, 递归右儿子
  2. 中序:递归左儿子, do(), 递归右儿子
  3. 后序:递归左儿子, 递归右儿子, do()

用自定义栈实现(迭代法)

首先首先首先!!!
明确前中后序遍历的本质,即二叉树节点的访问顺序:

  1. 前序:中 -> 左 -> 右
  2. 中序:左 -> 中 -> 右
  3. 后序:左 -> 右 -> 中

中代表直接访问了一次该节点,左右代表访问一次其左右儿子


随想录链接:https://programmercarl.com/二叉树的迭代遍历.html#前序遍历-迭代法

前序的写法:

模拟递归法即可,唯一需要注意点就是,因为用的自己的栈,故如果想先左后右,那么必须先入栈右儿子

点击查看代码
while len(stack) != 0:
    res.append(stack[-1].val)
    node = stack.pop()
    if node.right:
       stack.append(node.right)
    if node.left:
       stack.append(node.left)
------------- ### 中序的写法: 我最开始思路就是,不就是再模拟一次递归就好?故调整左右儿子入栈顺序。太天真了 其实前序遍历写法简单的关键在访问与处理刚好都是第一步,而中序是第二次访问才开始处理 故应该分步负责访问和处理 1. 用一个指针负责访问 1. 用栈维护处理节点的功能
p = root
while p or stack:
    if p:
        stack.append(p)
        p = p.left
    else:
        p = stack.pop()
        res.append(p.val)
        p = p.right

后序的写法:

这个是完全学习的随想录,实在没思路了。

先序遍历是中左右,后续遍历是左右中,那么我们只需要调整一下先序遍历的代码顺序,就变成中右左的遍历顺序,然后在反转result数组,输出的结果顺序就是左右中了,如下图:
image

故调整下前序法的顺序(注意先右后左):

while len(stack) != 0:
    res.append(stack[-1].val)
    node = stack.pop()
    if node.left:
        stack.append(node.left)
    if node.right:
        stack.append(node.right)

最后来个res.reverse()

基于标记法的一种统一思路

中序

前文谈到迭代法的中序的写法不统一:问题出在左中右的中,前序后续的中都在最开始访问或最后,故能写得很统一简洁。
那么我们就能用标记法来解决,即:

  1. 检测节点是否是首次访问
  2. 是则将其弹出,放入右,中,左
  3. 在放中的时候再放入一个空指针
  4. 再弹栈的时候,若有空指针,则代表检测到该节点已是第二次访问了,马上弹出并入res结果
点击查看代码
    def collectNode(self, node: TreeNode, res: List[int]):
        if node is None:
            return
        stack = [node]
        # 左中右
        # 放入栈顺序为 右中左
        while len(stack) != 0:
            node = stack[-1]
            if node:
                stack.pop()
                if node.right:
                    stack.append(node.right)
                stack.append(node)
                stack.append(None)
                if node.left:
                    stack.append(node.left)
            else:
                stack.pop()
                node = stack.pop()
                res.append(node.val)
----------------- ### 前序 and 后序 不难推出,仅需改变左右中对应的顺序即可实现统一的遍历(==再次强调入栈顺序需要相反==) ```python # 右 if node.right: stack.append(node.right) # 中 stack.append(node) stack.append(None) # 左 if node.left: stack.append(node.left) ```