数据结构-了解树和二叉树

一、了解树

1. 树的基本概念

树是一种非线性数据结构,主要用于表示层次关系。它由节点和连接这些节点的边组成。树的形状像一棵倒立的树,根部在上,树枝向下延伸。

2. 树的定义

树可以定义为一个空树或由以下性质的节点组成的非空集合:

  • 空树:没有任何节点的树。
  • 非空树:包含一个根节点和零个或多个子树的集合。

3. 基本术语

  • 节点(Node):树的基本元素,可以存储数据。每个节点可以有多个子节点。

  • 边(Edge):连接两个节点的线,表示父子关系。

  • 根节点(Root):树的顶端节点,没有父节点。每棵树只有一个根节点。

  • 叶子节点(Leaf):没有子节点的节点,位于树的最底层。

  • 子节点(Child):直接连接到某个节点的节点。

  • 父节点(Parent):直接连接到某个节点并且在其上方的节点。

  • 兄弟节点(Sibling):同一个父节点的子节点。

  • 深度(Depth):从根节点到该节点的边的数量。根节点的深度为0。

  • 高度(Height):从该节点到最远叶子节点的边的数量。叶子节点的高度为0。

  • 层(Level):树中节点的层数,根节点在第0层,根节点的子节点在第1层,以此类推。

  • 子树(Subtree):从某个节点开始的树,包括该节点及其所有后代节点。

  • 度(Degree):一个节点的度是它的子节点数量。

4. 森林

森林是由多个不相交的树组成的集合。可以将森林看作是多个树的组合。例如,如果我们从一棵树中删除根节点,剩下的子树就形成了一个森林。

5. 树的性质

  • 节点数量与边的关系:一棵有 n 个节点的树必定有 n−1 条边。这是因为每增加一个节点,就必须增加一条边来连接它。

  • 高度和节点数:树的高度与节点数量之间存在关系。对于一棵完全二叉树,节点数 n 和高度 h 的关系是n=2^(h+1) − 1。

  • 叶子节点的数量:在一棵树中,叶子节点的数量 L 和非叶子节点的数量 N 之间的关系是 L=N+1(对于二叉树)。

  • 树的遍历:树的遍历是指访问树中每个节点的过程。常见的遍历方式有:

    • 前序遍历(Pre-order):访问根节点,然后访问左子树,最后访问右子树。
    • 中序遍历(In-order):访问左子树,访问根节点,然后访问右子树。
    • 后序遍历(Post-order):访问左子树,访问右子树,然后访问根节点。

6. 树的类型

  • 二叉树:每个节点最多有两个子节点(左子节点和右子节点)。

  • 平衡树:树的高度尽量保持平衡,以优化查找效率,如AVL树和红黑树。

  • N叉树:每个节点可以有N个子节点。

  • Trie树:用于存储字符串的树,常用于词典和自动补全。

二、了解二叉树

1. 二叉树的定义

二叉树(Binary Tree) 是一种每个节点最多有两个子节点的数据结构。这两个子节点通常被称为左子节点和右子节点。

2. 基本术语

  • 根节点(Root):二叉树的顶端节点。
  • 叶子节点(Leaf):没有子节点的节点。
  • 深度(Depth):从根节点到该节点的边的数量。
  • 高度(Height):从该节点到最远叶子节点的边的数量。
  • 度(Degree):节点的子节点数量(0、1或2)。

3. 二叉树的性质

  1. 节点数量与高度

    • 一棵满二叉树的高度为 h 时,节点数量为 2^(h+1) − 1。
    • 一棵完全二叉树的高度为 h 时,节点数量在 2^h 到 2^(h+1) − 1 之间。
  2. 叶子节点数量

    • 在一棵二叉树中,如果有 n 个节点,叶子节点的数量 L 和非叶子节点的数量 N 之间的关系是:L=N+1

4. 特殊的二叉树

  1. 满二叉树(Full Binary Tree)

    • 每个节点要么是叶子节点,要么有两个子节点。
  2. 完全二叉树(Complete Binary Tree)

    • 除了最后一层外,其他层都是满的,且最后一层的节点尽可能地集中在左侧。
  3. 平衡二叉树(Balanced Binary Tree)

    • 任意节点的左右子树的高度差不超过1。
  4. 二叉搜索树(Binary Search Tree, BST)

    • 对于每个节点,左子树的所有节点的值小于该节点的值,右子树的所有节点的值大于该节点的值。

5. 二叉树的遍历

  1. 前序遍历(Pre-order):访问根节点 → 访问左子树 → 访问右子树。
  2. 中序遍历(In-order):访问左子树 → 访问根节点 → 访问右子树。
  3. 后序遍历(Post-order):访问左子树 → 访问右子树 → 访问根节点。
  4. 层序遍历(Level-order):按层访问节点,从上到下,从左到右。

6. K 叉树

K 叉树(K-ary Tree) 是一种每个节点最多有 K 个子节点的树结构。

  • 定义:K 叉树的每个节点可以有 0 到 K 个子节点。
  • 性质
    • K 叉树的节点数量与高度的关系类似于二叉树。例如,深度为 h 的 K 叉树的最大节点数为 [ K^(h+1)−1 ] / (K−1)。
    • K 叉树的遍历方法与二叉树类似,但在遍历时需要访问所有 K 个子节点。

三、二叉树的顺序存储

1. 二叉树顺序存储的定义

顺序存储 是将二叉树的节点按照一定顺序存储在数组中的一种方法。该方法适用于完全二叉树或满二叉树,因为它们的节点排列较为规则,便于使用数组进行存储。

2. 存储结构

在顺序存储中,通常使用一个一维数组来存储二叉树的节点。假设数组的下标从 0 开始,节点的存储规则如下:

  • 根节点 存储在数组的第 0 个位置(索引 0)。
  • 对于任意节点 ii(索引从 0 开始):
    • 左子节点的索引为 2*i+1
    • 右子节点的索引为 2*i+2
    • 父节点的索引为 (i−1)/2(向下取整)

3. 存储示例

假设有以下二叉树:

        A
       / \
      B   C
     / \   \
    D   E   F

这个二叉树的顺序存储可以表示为数组:

Index:  0   1   2   3   4   5
Array: [A,  B,  C,  D,  E,  F]
  • A (根节点) 存储在索引 0
  • B (左子节点) 存储在索引 1
  • C (右子节点) 存储在索引 2
  • D (B 的左子节点) 存储在索引 3
  • E (B 的右子节点) 存储在索引 4
  • F (C 的右子节点) 存储在索引 5

4. 优点

  • 简单直观:顺序存储结构简单,容易实现。
  • 随机访问:可以通过数组的下标快速访问任意节点,时间复杂度为 O(1)。
  • 空间利用率高:适用于完全二叉树,能有效利用数组空间。

5. 缺点

  • 空间浪费:对于不完全二叉树,可能会造成大量空闲空间。例如,如果树的高度很大,但节点数量很少,数组的大小可能会非常大。
  • 动态调整困难:在插入或删除节点时,可能需要频繁移动数组中的元素,导致效率降低。
  • 不适合稀疏树:对于稀疏的二叉树,顺序存储并不高效。

6. 适用场景

顺序存储适用于以下场景:

  • 完全二叉树或满二叉树的存储。
  • 节点数量相对固定且较少变化的二叉树。
  • 需要频繁访问节点的场景。

四、二叉树的链式存储

1. 二叉树链式存储的定义

链式存储 是通过节点之间的指针关系来存储二叉树的一种方式。每个节点不仅存储数据,还包含指向其左右子节点的指针。链式存储适用于任意形状的二叉树,特别是对于不完全二叉树或稀疏树。

2. 存储结构

在链式存储中,每个节点通常包含以下三个部分:

  • 数据域(Data):存储节点的值。
  • 左指针(Left Pointer):指向左子节点。
  • 右指针(Right Pointer):指向右子节点。
节点结构示例(C 语言)
cs 复制代码
// 定义二叉树节点结构
typedef struct TreeNode {
    int data;                // 数据域
    struct TreeNode* left;   // 左子节点指针
    struct TreeNode* right;  // 右子节点指针
}TreeNode , *BiTree;

3. 链式存储的优点

  • 灵活性高:可以动态调整树的结构,方便进行插入和删除操作。
  • 空间利用率高:只在需要时分配内存,避免了顺序存储中可能的空间浪费。
  • 适合稀疏树:对于不完全或稀疏的二叉树,链式存储能够有效利用内存。

4. 链式存储的缺点

  • 访问效率低:由于节点不连续存储,随机访问某个节点的时间复杂度为 O(n),而顺序存储为 O(1)。
  • 额外空间开销:每个节点需要额外的指针空间,增加了内存开销。

5. 构建链式存储的示例

假设我们要构建以下二叉树:

        A
       / \
      B   C
     / \   \
    D   E   F

我们可以通过链式存储来表示这个二叉树,节点之间的指针关系如下:

链式存储中,节点的指针将指向相应的子节点:

  • 节点 A 的左指针指向节点 B,右指针指向节点 C。
  • 节点 B 的左指针指向节点 D,右指针指向节点 E。
  • 节点 C 的右指针指向节点 F。

总结:

本文详细介绍了树和二叉树的基本概念、定义、术语、性质、以及不同的存储方式。以下是主要内容的概述:

一、树的基本概念

  • 树的定义:树是一种非线性数据结构,由节点和连接这些节点的边组成。树可以是空树或包含根节点及其子树的非空树。
  • 基本术语:包括根节点、叶子节点、深度、高度和度等。
  • 森林:由多个不相交的树组成的集合。
  • 树的性质:如前序、中序、后序遍历等。

二、二叉树

  • 定义:二叉树是一种每个节点最多有两个子节点的树结构。
  • 基本术语:包括根节点、叶子节点、深度、高度和度等。
  • 性质:如满二叉树和完全二叉树的节点数量关系,以及叶子节点和非叶子节点的关系。
  • 特殊的二叉树:如满二叉树、完全二叉树、平衡二叉树和二叉搜索树。
  • 遍历方式:包括前序遍历、中序遍历、后序遍历和层序遍历。
  • K叉树:每个节点最多有 K 个子节点的树结构。

三、二叉树的顺序存储

  • 定义:使用一维数组存储二叉树节点,适用于完全二叉树或满二叉树。
  • 存储结构:根节点存储在数组的第0个位置,子节点的索引规则明确。
  • 优点:简单直观、随机访问、空间利用率高。
  • 缺点:空间浪费、动态调整困难、不适合稀疏树。
  • 适用场景:适合完全二叉树和节点数量相对固定的二叉树。

四、二叉树的链式存储

  • 定义:通过节点之间的指针关系存储二叉树,适用于任意形状的二叉树。
  • 存储结构:每个节点包含数据域和左右子节点指针。
  • 优点:灵活性高、空间利用率高、适合稀疏树。
  • 缺点:访问效率低、额外空间开销。
  • 构建示例:通过链式存储表示特定的二叉树结构,展示节点之间的指针关系。
相关推荐
走向自由18 分钟前
Leetcode 最长回文子串
数据结构·算法·leetcode·回文·最长回文
nuo53420233 分钟前
The 2024 ICPC Kunming Invitational Contest
c语言·数据结构·c++·算法
luckilyil33 分钟前
Leetcode 每日一题 11. 盛最多水的容器
算法·leetcode
特种加菲猫39 分钟前
初阶数据结构之队列的实现
开发语言·数据结构·笔记
A.A呐1 小时前
LeetCode 1658.将x减到0的最小操作数
算法·leetcode
hn小菜鸡1 小时前
LeetCode 144.二叉树的前序遍历
算法·leetcode·职场和发展
rubyw1 小时前
如何选择聚类算法、回归算法、分类算法?
算法·机器学习·分类·数据挖掘·回归·聚类
编程探索者小陈1 小时前
【优先算法】专题——双指针
数据结构·算法·leetcode
Sunyanhui12 小时前
力扣 三数之和-15
数据结构·算法·leetcode
Mr.kanglong2 小时前
【LeetCode热题100】队列+宽搜
算法·leetcode·职场和发展