【数据结构】 树的遍历:先序、中序、后序和层序

server/2025/1/11 4:44:36/

数据结构中,树(Tree)作为一种基础的非线性结构,广泛应用于多种场景。树的遍历是树操作中的重要组成部分,它决定了我们如何访问树中的每一个节点。树的遍历方法有多种,每种方法适用于不同的场景,且每种方法的访问顺序不同。

本文将深入探讨四种常见的树的遍历方式:先序遍历中序遍历后序遍历层序遍历。我们将通过图示、符号表示以及清晰的解释,帮助你掌握这些遍历方法,并理解它们的应用场景和区别。

本文需要读者对数的概念有基本认知,若不了解可参考以下博文

文章目录

    • 树的基本概念
      • 树的定义
      • 深度优先遍历(DFS)
      • 广度优先遍历(BFS)
    • 先序遍历(Preorder Traversal)
      • 定义
      • 示例
      • 代码示例
    • 中序遍历(Inorder Traversal)
      • 定义
      • 示例
      • 代码示例
    • 后序遍历(Postorder Traversal)
      • 定义
      • 示例
      • 代码示例
    • 层序遍历(Level Order Traversal)
      • 定义
      • 示例
      • 层序遍历的代码示例
    • 总结

树的基本概念

树的定义

树是一种由节点(Node)和边(Edge)组成的层次型数据结构。树中有一个唯一的根节点(Root Node),每个节点可以有多个子节点(Child Node),但只能有一个父节点(Parent Node)。树的节点之间通过边相连,形成一个有序的层级结构。

例如,一棵简单的二叉树(Binary Tree)可能如下所示:

        A/ \B   C/ \   \D   E   F

在这棵树中:

  • 根节点是A。
  • B和C是A的子节点。
  • D和E是B的子节点,F是C的子节点。
  • D、E、F都是叶子节点(没有子节点)。

树的遍历方法决定了我们访问节点的顺序。树的遍历可以分为两类:深度优先遍历(DFS)和广度优先遍历(BFS)。

深度优先遍历(DFS)

深度优先遍历是指从树的根节点开始,沿着树的深度遍历尽可能深的节点。深度优先遍历有三种常见的方式:先序遍历、中序遍历和后序遍历。

广度优先遍历(BFS)

广度优先遍历是指从树的根节点开始,先访问根节点的所有子节点,再逐层向下访问其他节点。广度优先遍历又叫层序遍历。

先序遍历(Preorder Traversal)

定义

先序遍历是深度优先遍历的一种方式。其遍历顺序为:

  1. 访问根节点。
  2. 遍历左子树。
  3. 遍历右子树。

在先序遍历中,根节点总是最先被访问,因此这种遍历方法也被称为根-左-右遍历。

示例

我们以下面这棵二叉树为例,来说明先序遍历的过程:

        A/ \B   C/ \   \D   E   F

先序遍历的步骤:

  1. 访问根节点A。
  2. 遍历A的左子树(B)。
    • 访问根节点B。
    • 遍历B的左子树(D)。
      • 访问节点D。
    • 遍历B的右子树(E)。
      • 访问节点E。
  3. 遍历A的右子树(C)。
    • 访问根节点C。
    • 遍历C的右子树(F)。
      • 访问节点F。

先序遍历的顺序为: A → B → D → E → C → F。

代码示例

class TreeNode:def __init__(self, value):self.value = valueself.left = Noneself.right = Nonedef preorder_traversal(root):if root:print(root.value, end=' ')  # 访问根节点preorder_traversal(root.left)  # 遍历左子树preorder_traversal(root.right)  # 遍历右子树# 构造示例树
root = TreeNode('A')
root.left = TreeNode('B')
root.right = TreeNode('C')
root.left.left = TreeNode('D')
root.left.right = TreeNode('E')
root.right.right = TreeNode('F')preorder_traversal(root)  # 输出: A B D E C F

中序遍历(Inorder Traversal)

定义

中序遍历是深度优先遍历的另一种方式。其遍历顺序为:

  1. 遍历左子树。
  2. 访问根节点。
  3. 遍历右子树。

在中序遍历中,根节点位于左子树和右子树之间,因此这种遍历方法也被称为左-根-右遍历。

示例

以相同的二叉树为例,说明中序遍历的过程:

        A/ \B   C/ \   \D   E   F

中序遍历的步骤:

  1. 遍历A的左子树(B)。
    • 遍历B的左子树(D)。
      • 访问节点D。
    • 访问根节点B。
    • 遍历B的右子树(E)。
      • 访问节点E。
  2. 访问根节点A。
  3. 遍历A的右子树(C)。
    • 遍历C的右子树(F)。
      • 访问节点F。
    • 访问节点C。

中序遍历的顺序为: D → B → E → A → F → C。

代码示例

def inorder_traversal(root):if root:inorder_traversal(root.left)  # 遍历左子树print(root.value, end=' ')  # 访问根节点inorder_traversal(root.right)  # 遍历右子树inorder_traversal(root)  # 输出: D B E A F C

后序遍历(Postorder Traversal)

定义

后序遍历是深度优先遍历的第三种方式。其遍历顺序为:

  1. 遍历左子树。
  2. 遍历右子树。
  3. 访问根节点。

在后序遍历中,根节点最后被访问,因此这种遍历方法也被称为左-右-根遍历。

示例

以相同的二叉树为例,说明后序遍历的过程:

        A/ \B   C/ \   \D   E   F

后序遍历的步骤:

  1. 遍历A的左子树(B)。
    • 遍历B的左子树(D)。
      • 访问节点D。
    • 遍历B的右子树(E)。
      • 访问节点E。
    • 访问根节点B。
  2. 遍历A的右子树(C)。
    • 遍历C的右子树(F)。
      • 访问节点F。
    • 访问节点C。
  3. 访问根节点A。

后序遍历的顺序为: D → E → B → F → C → A。

代码示例

def postorder_traversal(root):if root:postorder_traversal(root.left)  # 遍历左子树postorder_traversal(root.right)  # 遍历右子树print(root.value, end=' ')  # 访问根节点postorder_traversal(root)  # 输出: D E B F C A

层序遍历(Level Order Traversal)

定义

层序遍历是一种广度优先遍历方法。其遍历顺序为:

  1. 访问根节点。
  2. 按层次从上到下、从左到右依次访问树的其他节点。

层序遍历采用队列(Queue)来实现,因为队列遵循先进先出(FIFO)的特性,能够确保按层次遍历。

示例

以相同的二叉树为例,说明层序遍历的过程:

        A/ \B   C/ \   \D   E   F

层序遍历的步骤:

  1. 访问根节点A。
  2. 访问A的子节点B和C。
  3. 访问B的子节点D和E,访问C的子节点F。

层序遍历的顺序为: A → B → C → D → E → F。

层序遍历的代码示例

from collections import dequedef level_order_traversal(root):if not root:returnqueue = deque([root])  # 初始化队列,先将根节点入队while queue:node = queue.popleft()  # 出队一个节点print(node.value, end=' ')  # 访问节点if node.left:queue.append(node.left)  # 将左子节点入队if node.right:queue.append(node.right)  # 将右子节点入队level_order_traversal(root)  # 输出: A B C D E F

总结

树的遍历是理解和操作树数据结构的基础。通过对先序遍历、中序遍历、后序遍历和层序遍历的学习,我们能够更好地掌握树的结构和如何在不同的应用场景中访问节点。最重要的是树的遍历是考研当中几乎是必考的内容(最最最重要的)。


http://www.ppmy.cn/server/157374.html

相关文章

【EI,Scopus检索 | 往届均已检索见刊】第四届智能系统、通信与计算机网络国际学术会议(ISCCN 2025)

重要信息: 大会官网:更多详情【论文投稿】 截稿时间:以官网信息为准 大会时间:2025年2月21-23日 接受/拒稿通知:投稿后3-5个工作日内 收录检索:EI,Scopus 出版信息: 本会议所有…

cursor试用出现:Too many free trial accounts used on this machine 的解决方法

文章精选推荐 1 JetBrains Ai assistant 编程工具让你的工作效率翻倍 2 Extra Icons:JetBrains IDE的图标增强神器 3 IDEA插件推荐-SequenceDiagram,自动生成时序图 4 BashSupport Pro 这个ides插件主要是用来干嘛的 ? 5 IDEA必装的插件&…

2025新年源码免费送

2025很开门很开门的源码免费传递。不需要馒头就能获取4套大开门源码。 听泉偷宝,又进来偷我源码啦👊👊👊。欢迎偷源码 🔥🔥🔥 获取免费源码以及更多源码,可以私信联系我 我们常常…

Github 2025-01-08 C开源项目日报 Top10

根据Github Trendings的统计,今日(2025-01-08统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量C项目10Shell项目1Redis - 内存数据库和数据结构服务器 创建周期:5411 天开发语言:C协议类型:BSD 3-Clause “New” or “Revised” License…

腾讯云大数据智能管家:AI驱动管理效能飞升

点击蓝字⬆ 关注我们 本文共计1241 预计阅读时长4分钟 在大数据时代,海量数据的产生给企业带来了新的机遇,也带来了复杂的管理挑战。如何高效利用数据资源、降低运维成本、提升系统性能成为每个企业的共同难题。腾讯云推出的大数据智能管家,以…

阿里巴巴新零售模式下的创新实践:结合开源AI智能名片2+1链动模式S2B2C商城小程序的应用探索

摘要:在数字经济浪潮的推动下,新零售作为传统零售与现代信息技术深度融合的产物,正逐步改变着零售行业的面貌。阿里巴巴作为新零售战略的倡导者和实践者,通过整合线上线下资源,利用大数据、云计算等先进技术&#xff0…

HTML 音频(Audio)

HTML 音频(Audio) HTML5 引入了新的音频标签 <audio>,使得在网页上嵌入音频文件变得更加简单。在此之前,播放音频通常需要依赖于第三方插件,如 Flash。但随着 HTML5 的普及,浏览器原生支持音频播放,极大地提升了用户体验和网页性能。 基本用法 要使用 HTML5 的音…

JavaScript 实现支持过期时间的数据缓存功能

JavaScript 实现支持过期时间的数据缓存功能 要在 JavaScript 中实现数据缓存功能并支持设置过期时间&#xff0c;可以使用 localStorage、sessionStorage 或内存对象&#xff08;如 Map 或普通对象&#xff09;来存储数据&#xff0c;并为每个缓存项设置一个过期时间。以下是…