LeetCode——迭代遍历算法

在计算机科学中,遍历算法是处理数据结构的基础操作,而迭代遍历作为其中的重要方式,凭借其高效的内存利用和稳定的性能,在实际开发中被广泛应用。与递归遍历相比,迭代遍历通过循环结构实现,避免了函数调用栈可能带来的溢出风险,尤其在处理大规模数据时更具优势。本文将从基础概念出发,结合 Python 代码实例,深入解析迭代遍历在不同数据结构中的应用,并通过力扣题目展示其实战价值。

迭代遍历的核心思想

迭代遍历的本质是通过显式的循环结构辅助数据结构(通常是栈或队列)来模拟递归过程中隐式的函数调用栈。其核心步骤包括:初始化遍历起点,定义循环终止条件,在每次循环中处理当前元素并更新遍历状态。这种方式的优势在于:

  • 内存可控:不会因递归深度过大导致栈溢出
  • 执行效率高:减少了函数调用的额外开销
  • 调试友好:循环过程中的变量状态更容易追踪

在 Python 中,迭代遍历通常使用 while 循环配合列表(模拟栈或队列)实现,对于不同的数据结构(如二叉树、图、链表等),需要设计针对性的遍历策略。

二叉树的迭代遍历实现

二叉树作为典型的非线性数据结构,其迭代遍历是算法面试中的高频考点。以下分别实现前序、中序和后序三种遍历方式。

前序遍历(根 - 左 - 右)

前序遍历的关键是先访问根节点,再依次遍历左子树和右子树。迭代实现时,使用栈存储待访问节点,每次弹出栈顶元素并处理,然后按右子树先入栈、左子树后入栈的顺序保持遍历顺序:

ini 复制代码
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
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

中序遍历(左 - 根 - 右)

中序遍历需要先遍历左子树,再访问根节点,最后遍历右子树。实现时需先将所有左节点入栈,直到叶子节点,再依次弹出处理:

ini 复制代码
def inorder_traversal(root):
    if not root:
        return []
    stack = []
    result = []
    current = root
    while stack or current:
        # 将所有左节点入栈
        while current:
            stack.append(current)
            current = current.left
        # 弹出最左节点并处理
        current = stack.pop()
        result.append(current.val)
        # 转向右子树
        current = current.right
    return result

后序遍历(左 - 右 - 根)

后序遍历可通过前序遍历的变种实现:先按 "根 - 右 - 左" 顺序遍历,再反转结果即可得到 "左 - 右 - 根" 的后序序列:

ini 复制代码
def postorder_traversal(root):
    if not root:
        return []
    stack = [root]
    result = []
    while stack:
        node = stack.pop()
        result.append(node.val)
        # 左子树先入栈,保证右子树先处理
        if node.left:
            stack.append(node.left)
        if node.right:
            stack.append(node.right)
    # 反转得到后序遍历结果
    return result[::-1]

力扣实战:二叉树的层序遍历

层序遍历(广度优先遍历)需要按层次依次访问节点,通常使用队列实现。以下解析力扣第 102 题 "二叉树的层序遍历" 的解决方案。

题目分析

题目描述:给你二叉树的根节点 root,返回其节点值的层序遍历(即逐层地,从左到右访问所有节点)。

示例

输入:root = [3,9,20,null,null,15,7]

输出:[[3],[9,20],[15,7]]

算法设计

层序遍历的核心是按层处理节点,每次循环处理当前层的所有节点,并将下一层节点存入队列。具体步骤:

  1. 初始化队列,将根节点入队
  1. 当队列不为空时,记录当前层节点数量
  1. 依次弹出当前层节点,将节点值存入当前层结果
  1. 将当前层节点的左右子节点入队
  1. 将当前层结果加入总结果列表

代码实现

ini 复制代码
def level_order(root):
    if not root:
        return []
    from collections import deque  # 使用双端队列提高弹出效率
    queue = deque([root])
    result = []
    while queue:
        level_size = len(queue)  # 当前层节点数量
        current_level = []
        for _ in range(level_size):
            node = queue.popleft()  # 弹出队首元素
            current_level.append(node.val)
            # 左子节点先入队
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        result.append(current_level)
    return result

复杂度分析

  • 时间复杂度:O (n),其中 n 为二叉树节点总数,每个节点恰好被访问一次
  • 空间复杂度:O (m),其中 m 为层节点数的最大值,最坏情况下(完美二叉树)为 O (n/2)

迭代遍历的扩展应用

除了二叉树,迭代遍历还广泛应用于其他数据结构:

  • 图的遍历:深度优先遍历(DFS)使用栈,广度优先遍历(BFS)使用队列
  • 链表操作:如反转链表、寻找倒数第 k 个节点等问题
  • 字符串处理:如括号匹配、表达式求值等场景

以图的深度优先遍历为例,其迭代实现与二叉树前序遍历类似:

arduino 复制代码
def dfs_iterative(graph, start):
    visited = set()
    stack = [start]
    while stack:
        node = stack.pop()
        if node not in visited:
            visited.add(node)
            # 将邻接节点入栈(逆序保证遍历顺序)
            for neighbor in reversed(graph[node]):
                stack.append(neighbor)
    return visited

总结

迭代遍历算法通过显式的循环和辅助数据结构,实现了对各类数据结构的高效访问。相比递归方式,它在内存管理和执行效率上更具优势,尤其适合处理大规模数据或深度不确定的场景。

在实际应用中,需根据具体数据结构的特点选择合适的遍历策略:二叉树的前中后序遍历常用栈实现,层序遍历则依赖队列;图的遍历可根据需求选择深度优先(栈)或广度优先(队列)方式。

掌握迭代遍历的核心思想,不仅能解决各类算法问题,更能培养对数据流动的深刻理解,为复杂程序设计打下坚实基础。建议通过更多力扣题目(如二叉树的锯齿形层序遍历、N 叉树的前序遍历等)进行强化练习,深化对迭代思想的运用。

相关推荐
mochensage1 分钟前
贪心算法
算法·信奥
yi.Ist33 分钟前
8.4 Codeforces练习
算法
HW-BASE34 分钟前
C语言控制语句练习题1
c语言·开发语言·单片机·算法·嵌入式·c
weixin_4786897636 分钟前
算法【3】【链表 & 二叉树】
算法
KoiHeng1 小时前
排序算法(二)
算法·排序算法
源远流长jerry2 小时前
C++、STL面试题总结(一)
c++·算法
穆霖祎3 小时前
数据结构(4)
数据结构
yanxing.D3 小时前
考研408_数据结构笔记(第四章 串)
数据结构·笔记·考研·算法
庸子3 小时前
云平台托管集群:EKS、GKE、AKS 深度解析与选型指南-第四章
算法·贪心算法