考研数据结构之树与森林

考研数据结构之树与森林

树与森林是数据结构中的重要非线性结构,其与二叉树的相互转换是考研高频考点。本文系统梳理树的存储结构、树/森林与二叉树的转换规则,以及遍历方法,结合真题解析帮助读者掌握核心逻辑。


一、树的存储结构

树的存储需同时记录节点数据及其逻辑关系,常用方法有以下三种:

1. 双亲表示法

  • 原理:用数组顺序存储节点,并为每个节点附加一个parent域,记录其父节点的数组下标。
  • 特点
    • 查找父节点时间复杂度为O(1),但查找子节点需遍历整个数组。
    • 适合需要频繁访问父节点的场景(如并查集)。
  • 示例
    struct Node {
        int data;
        int parent; // 父节点索引
    };
    

2. 孩子表示法

  • 实现方式
    • 方法一:为每个节点固定分配多个指针域指向子节点(定长结点法)。
    • 方法二:使用链表动态存储子节点(孩子链表法)。
  • 特点
    • 灵活支持多子节点,但空间开销较大。
    • 适合需要频繁访问子树的场景。

3. 孩子兄弟表示法(链式存储)

  • 结构定义:每个节点包含两个指针域,分别指向第一个孩子下一个兄弟
    typedef struct CSNode {
        int data;
        struct CSNode *firstChild; // 指向第一个孩子
        struct CSNode *nextSibling; // 指向下一个兄弟
    } CSNode;
    
  • 核心作用:为树与二叉树的转换提供直接支持(详见下文)。

二、树、森林与二叉树的转换

1. 树 → 二叉树

  • 转换规则
    1. 左孩子右兄弟:将每个节点的左指针指向其第一个孩子,右指针指向其下一个兄弟。
    2. 根节点无右子树:转换后的二叉树根节点右子树必为空。
  • 示例
    原树:        A              转换后二叉树:A
               / | \                         /
              B  C  D                       B
                                            \  
                                             C
                                              \
                                               D
    

2. 森林 → 二叉树

  • 步骤
    1. 将森林中每棵树转换为二叉树。
    2. 将每棵二叉树的根节点依次连接为右子树。
  • 关键点:森林中各树的根节点互为兄弟,构成二叉树的右子树链。

3. 二叉树 → 树/森林

  • 判断依据
    • 若二叉树根节点有右子树,则可转换为森林
    • 若根节点无右子树,则转换为单棵树
  • 逆转换规则
    1. 将二叉树按左孩子右兄弟规则分解。
    2. 断开右子树链,恢复为多棵树。

三、树与森林的遍历

1. 树的遍历

  • 先根遍历
    • 访问根节点 → 依次先根遍历每棵子树。
    • 等价于转换后二叉树的先序遍历
  • 后根遍历
    • 依次后根遍历每棵子树 → 访问根节点。
    • 等价于转换后二叉树的中序遍历

2. 森林的遍历

  • 先序遍历
    1. 访问森林中第一棵树的根节点。
    2. 先序遍历第一棵树的子树森林。
    3. 先序遍历剩余树构成的森林。
  • 中序遍历
    1. 中序遍历第一棵树的子树森林。
    2. 访问第一棵树的根节点。
    3. 中序遍历剩余树构成的森林。

四、真题解析

1. 树的存储结构应用

题目(改编自):

已知树的双亲表示法存储结构如下:
data = [A, B, C, D], parent = [-1, 0, 0, 1]
请画出该树的逻辑结构。

解析

  • 索引0为根节点A(parent=-1)。
  • 索引1的B和索引2的C的父节点为A(parent=0)。
  • 索引3的D的父节点为B(parent=1)。
    答案
    A
   / \
  B   C
 /
D

2. 树与二叉树的转换

题目(经典真题,):

将以下树转换为二叉树,并写出其先序和中序遍历序列。

    A
   / \
  B   C
 / \
D   E

解析

  • 转换结果
        A
       /
      B
     / \
    D   C
     \
      E
    
  • 先序序列A B D E C(等同原树的先根遍历)。
  • 中序序列D E B C A(等同原树的后根遍历)。

3. 森林的遍历序列

题目(2023年真题,):

森林F由两棵树构成:

第一棵树:    A          第二棵树:    B
            / \                     \
           C   D                     E

写出森林F的先序和中序遍历序列。

解析

  • 先序遍历
    1. 访问A → 先序遍历A的子树(C, D)。
    2. 访问B → 先序遍历B的子树(E)。
      结果A C D B E
  • 中序遍历
    1. 中序遍历A的子树(C, D)→ 访问A。
    2. 中序遍历B的子树(E)→ 访问B。
      结果C D A E B

五、总结

  • 存储结构:双亲表示法适合查找父节点,孩子兄弟表示法是转换二叉树的基础。
  • 转换规则:左孩子右兄弟是树与二叉树互转的核心逻辑。
  • 遍历等价性:树的先根遍历等同二叉树的先序,后根遍历等同二叉树的中序。

掌握这些知识点,可高效解决树与森林相关的遍历、转换及存储问题。后续文章将探讨平衡二叉树与哈夫曼树等进阶内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

老北京儿码农

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

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

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

打赏作者

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

抵扣说明:

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

余额充值