当前位置: 首页 > article >正文

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

一、了解树

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 语言)
// 定义二叉树节点结构
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个位置,子节点的索引规则明确。
  • 优点:简单直观、随机访问、空间利用率高。
  • 缺点:空间浪费、动态调整困难、不适合稀疏树。
  • 适用场景:适合完全二叉树和节点数量相对固定的二叉树。

四、二叉树的链式存储

  • 定义:通过节点之间的指针关系存储二叉树,适用于任意形状的二叉树。
  • 存储结构:每个节点包含数据域和左右子节点指针。
  • 优点:灵活性高、空间利用率高、适合稀疏树。
  • 缺点:访问效率低、额外空间开销。
  • 构建示例:通过链式存储表示特定的二叉树结构,展示节点之间的指针关系。


http://www.kler.cn/a/289014.html

相关文章:

  • 删库跑路,启动!
  • sealos部署K8s,安装docker时master节点突然NotReady
  • 2个word内容合并
  • Java算法OJ(7)随机快速排序
  • ARM架构中断与异常向量表机制解析
  • 【计算机网络】TCP网络程序
  • 科研绘图系列:python语言聚类图(hclust plot)
  • mysql高级知识之集群
  • Ascend C算子开发(入门)—— 算子开发初体验
  • C++笔记---模板初阶
  • 论文速览【LLM】 —— 【ORLM】Training Large Language Models for Optimization Modeling
  • 多线程——创建
  • UDP广播、 组播通信
  • macos 使用port查询并安装python2, python3多版本, 设置默认python版本方法
  • 算法训练营|图论第8天 拓扑排序 dijkstra
  • 【笔试练习】深信服校园招聘c/c 软件开发H卷
  • 使用python导出Excel表格中的lua配置
  • 初识Linux · 有关makefile
  • 【Rust光年纪】化学计算不完全指南:Rust语言库全面解析
  • jenv 一款macos下的开源JAVA多版本环境安装管理切换工具
  • Swift concurrency 5 — async let的理解与使用
  • 聊聊随机测试和猴子测试
  • Python参数传递的艺术:解锁编程灵活性的秘密武器
  • uniapp写的一个年月日时分秒时间选择功能
  • 【数据结构初阶】——栈和队列
  • 求三元组中可能出现的最小距离