数据结构之深入了解树结构

一、树的基本概念

1. 树的定义

树是一种非线性的数据结构,可以用二元组 T=(D,R) 表示,其中:

  • D 是数据元素的集合
  • R 是元素间关系的集合

树具有以下特性:

  • 当 n=0 时为空树
  • 当 n>0 时,有且仅有一个没有前驱的节点(称为根节点)
  • 除根节点外,其他节点有且仅有一个前驱,可以有多个后继

递归定义:树是 n=0 的空树,或者 n>0 时由根节点和 m 个互不相交的子树构成

2. 树的相关定义

  • :节点的后继节点个数。度为0的节点称为叶子节点,度不为0的称为分支节点

  • :连接相邻两个节点的连线。两个节点之间的路径是唯一的

  • 路径长度:树有 n-1 条边

  • 深度:从根节点到该节点的路径长度(通常根节点深度为0或1)

  • 高度:从节点到叶子节点的最长路径上的边数

  • 兄弟节点:具有相同双亲节点的节点互为兄弟

二、树的存储结构

1. 双亲结点表示法(父指针表示法)

适用场景:快速查找父节点。
存储方式:每个节点保存父节点的索引/指针。

struct ParentTreeNode {
    int data;
    int parentIndex; // 根节点为-1
};

vector<ParentTreeNode> tree = {
    {1, -1},  // 根节点A
    {2, 0},   // B的父节点是A
    {3, 0},   // C的父节点是A
    {4, 1}    // D的父节点是B
};

2. 孩子表示法(邻接表)

适用场景:需要频繁访问子节点(如文件系统)。
存储方式:每个节点维护一个子节点列表。

struct ChildTreeNode {
    int data;
    vector<ChildTreeNode*> children;
};

// 构建树 A(B(D), C)
ChildTreeNode* root = new ChildTreeNode{1, {
    new ChildTreeNode{2, {
        new ChildTreeNode{4, {}}
    }},
    new ChildTreeNode{3, {}}
}};

3. 孩子兄弟表示法(二叉树表示法)

适用场景:将普通树转为二叉树存储(左孩子右兄弟)。
存储方式

        左指针:指向第一个孩子

        右指针:指向下一个兄弟

4. 顺序存储(数组表示)

适用场景:完全二叉树/堆。
存储方式:按层级顺序存入数组。

vector<int> tree = {1, 2, 3, 4, -1, -1, 5}; 
// -1表示空节点
// 对应树结构:
//     1
//    / \
//   2   3
//  /     \
// 4       5

父节点索引:(i-1)/2

左子节点:2i+1

右子节点:2i+2

三、二叉树

1. 二叉树的定义

二叉树是每个节点最多有两个子节点的树结构,分别称为左子树和右子树。

2. 特殊二叉树类型

2.1 满二叉树

        (1)所有节点的度都为2

        (2)叶子节点都在最底层

        (3)高度为h的满二叉树有2^h-1个节点

2.2 完全二叉树

        (1)除最后一层外,其他层都是满的

        (2)最后一层节点靠左排列

        (3)适合用数组存储

2.3 二叉搜索树(BST)

        (1)左子树所有节点值小于根节点值

        (2)右子树所有节点值大于根节点值

        (3)中序遍历可以得到有序序列

对于序列13,9,42,3,5,1,19,72,32,7,4,构建的BST如下:

        13
      /    \
     9     42
    / \    / \
   3   19 32 72
  / \  /
 1 5 7
    /
   4
2.4 平衡二叉搜索树

AVL树:任意节点的左右子树高度差不超过1

红黑树:通过颜色标记保持近似平衡

四、堆结构

1. 堆的定义

堆是基于完全二叉树实现的一种特殊数据结构:

  • 最大堆:父节点值大于等于子节点值

  • 最小堆:父节点值小于等于子节点值

2. 堆的存储

堆通常用数组存储,对于索引为n的节点:

  • 父节点索引:(n-1)/2

  • 左子节点索引:2n+1

  • 右子节点索引:2n+2

3. 堆的应用

  • 堆排序:时间复杂度O(nlogn)的不稳定排序算法
  • 优先级队列:高效获取最大/最小元素的数据结构

五、哈夫曼树

1. 基本概念

哈夫曼树是带权路径长度最短的二叉树,用于数据压缩编码

  • 定长编码:如ANSI、GB2312/GBK

  • 变长编码:如UTF-8(1-4字节)

2. 哈夫曼树特性

  • 叶子节点数 = 分支节点数 + 1

  • 没有度为1的节点

  • 权值越大的节点离根越近

3. 构建步骤

  1. 将所有权值作为单独的树

  2. 选择权值最小的两棵树合并,新树根节点权值为两者之和

  3. 重复步骤2直到只剩一棵树

六、树的遍历

1. 二叉树的遍历方式

        A
      /   \
     B     C
    / \   /
   D   E F
  / 
 G 
  • 先序遍历:ABDGECF(根-左-右)

  • 中序遍历:GDBEAFC(左-根-右)

  • 后序遍历:GDEBFCA(左-右-根)

  • 层序遍历:ABCDEFG(按层次从上到下、从左到右)

2. 遍历应用

  • 先序遍历:复制树结构

  • 中序遍历:BST获取有序序列

  • 后序遍历:计算表达式树

  • 层序遍历:查找最短路径

七、树结构的实际应用

  1. 文件系统:目录树结构

  2. 数据库索引:B树、B+树

  3. 网络路由:路由表树

  4. 游戏AI:决策树

  5. XML/HTML解析:DOM树

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值