中序遍历(基于栈的非递归实现)和层序遍历(基于队列的实现)是二叉树遍历中的两种重要方法

中序遍历(基于栈的非递归实现)和层序遍历(基于队列的实现)是二叉树遍历中的两种重要方法,分别体现了深度优先与广度优先的访问策略。

  1. 中序遍历(非递归,基于栈)
def inorder_traversal(root):
    stack = []
    result = []
    current = root
    while current or stack:
        # 一直向左走到底,将路径上节点入栈
        while current:
            stack.append(current)
            current = current.left
        # 当前为空,弹出栈顶并访问
        current = stack.pop()
        result.append(current.val)  # 访问节点
        current = current.right  # 转向右子树
    return result

该方式模拟了递归调用的过程,通过显式使用栈来保存回溯路径,确保在访问完左子树后能正确回到根节点再进入右子树。

  1. 层序遍历(基于队列)
from collections import deque

def level_order_traversal(root):
    if not root:
        return []
    queue = deque([root])
    result = []
    while queue:
        node = queue.popleft()
        result.append(node.val)
        if node.left:
            queue.append(node.left)
        if node.right:
            queue.append(node.right)
    return result

利用先进先出的队列特性,保证每一层的节点按从左到右顺序被处理,适合用于求解树的层次结构相关问题,如层平均值、最大宽度等。

补充说明中强调:不同遍历方式生成的线性序列反映了不同的逻辑顺序。例如:

  • 中序遍历对二叉搜索树可得到升序序列;
  • 层序遍历则揭示了树的层级分布。

这些序列中所谓的“前驱”与“后继”关系依赖于具体的遍历规则,并无全局统一性。
前序遍历和后序遍历的非递归实现同样基于栈结构,但访问节点的顺序不同,因此入栈策略也有所区别。

1. 前序遍历(根 → 左 → 右)非递归实现

核心思想:使用栈模拟递归过程。每次弹出一个节点并访问,然后先将其右子节点入栈,再将左子节点入栈(确保左子树优先被处理)。

def preorder_traversal(root):
    if not root:
        return []
    stack = [root]
    result = []
    while stack:
        node = stack.pop()
        result.append(node.val)
        # 先压右再压左,保证左子树先出栈
        if node.right:
            stack.append(node.right)
        if node.left:
            stack.append(node.left)
    return result

2. 后序遍历(左 → 右 → 根)非递归实现

后序遍历较复杂,因为根节点必须在左右子树都访问完之后才能输出。常用方法是“双栈法”或“标记法”。这里介绍简洁高效的双栈法
思路

  • 第一个栈用于遍历,顺序为:根 → 左 → 右(类似前序);
  • 将访问的节点按此顺序压入第二个栈;
  • 最终从第二个栈弹出时,顺序变为:根 ← 右 ← 左,即后序的逆序。
def postorder_traversal(root):
    if not root:
        return []
    stack1 = [root]  # 主栈,用于遍历
    stack2 = []      # 辅助栈,记录逆序结果
    while stack1:
        node = stack1.pop()
        stack2.append(node)
        # 先压左再压右,保证右子树先处理
        if node.left:
            stack1.append(node.left)
        if node.right:
            stack1.append(node.right)
    # 弹出辅助栈得到后序序列
    result = []
    while stack2:
        result.append(stack2.pop().val)
    return result

💡 提示:也可以用单栈+指针标记已访问子树的方式实现,但双栈更直观易懂。


总结对比

遍历方式访问顺序栈操作特点
前序根 → 左 → 右直接弹出访问,先压右后压左
中序左 → 根 → 右一路向左入栈,为空则弹出访问并转向右
后序左 → 右 → 根使用双栈,模拟反向输出

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bol5261

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值