C语言数据结构——详细讲解《二叉树与堆的基本概念》

  • 前言
  • 一、树的基础概念
    • 1.1 为什么需要树?
    • 1.2 树的定义与结构
    • 1.3 树的核心术语
    • 1.3 树的核心术语
    • 1.4 树的表示方法(孩子兄弟表示法)
      • 结构定义
      • 为什么用孩子兄弟表示法?
    • 1.5 树的实际应用场景
  • 二、二叉树的概念与特性
    • 2.1 为什么重点研究二叉树?
    • 2.2 二叉树的定义与核心特点
    • 2.3 特殊的二叉树
      • 2.3.1 满二叉树
      • 2.3.2 完全二叉树
    • 2.4 二叉树的重要性质
  • 三、二叉树的存储结构
    • 3.1 顺序存储(数组存储)
      • 原理
      • 示例(完全二叉树的顺序存储)
    • 3.2 链式存储(二叉链)
      • 原理
      • 结构定义(C语言)
      • 示例(二叉链结构)
  • 四、堆的概念与基础实现
    • 4.1 堆是什么?
    • 4.2 堆的定义与核心条件
    • 4.3 堆的存储(数组顺序存储)
      • 示例1:大根堆的数组存储
      • 示例2:小根堆的数组存储


前言

  • 在上一篇博客中,我们探讨了队列这种线性数据结构,而此前学习的栈也属于线性结构——它们的元素都遵循“一对一”的线性逻辑关系。但在实际场景中,很多数据需要“一对多”的层级关系描述(比如文件系统、部门组织架构),此时线性结构就显得力不从心。
  • 今天,我们将进入非线性数据结构的世界,从最基础的“树”入手,逐步聚焦到应用最广泛的“二叉树”,最终讲解一种特殊的二叉树——“堆”。这三者层层递进,是后续学习高级数据结构(如红黑树、B+树)的核心基础。

我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343
我的C语言数据结构专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_12830540.html?spm=1001.2014.3001.5482


一、树的基础概念

在学习二叉树前,我们必须先理解“树”的本质——它是所有层级结构数据的“通用模型”,而二叉树是树的“简化版”。

1.1 为什么需要树?

在这里插入图片描述

假设我们要存储“电脑文件系统”的结构:C盘下有用户系统两个文件夹,用户下又有文档图片……
在这里插入图片描述

  • 如果用数组或链表(线性结构)存储,只能按“C盘→用户→文档→图片→系统”的顺序排列,无法体现“父子文件夹”的层级关系。而树的“一对多”结构,恰好能完美描述这种层级逻辑。
树的核心价值:解决“层级数据”的存储与访问问题,弥补线性结构在“一对多”关系中的不足。

1.2 树的定义与结构

树是由n(n≥0)个有限结点组成的具有层次关系的集合,满足以下规则:

  • 有且仅有一个根结点(如文件系统的“C盘”),根结点没有前驱结点;
  • 除根结点外,其余结点被分成m(m>0)个互不相交的子集(如“用户”“系统”文件夹),每个子集都是一棵独立的“子树”;
  • 子树之间不能相交(否则就变成了“图”,而非树);
  • 一棵有N个结点的树,必有N-1条边(每个结点除根外,都只通过一条边连接父结点)。

在这里插入图片描述

在这里插入图片描述

1.3 树的核心术语

树的术语较多,下面我们详细讲解一下

1.3 树的核心术语

树的术语较多,且需结合具体结构理解,我们以图示的树(根为A,子节点包含B、C、D、E、F、G等)为例,详细讲解:

术语定义示例(基于图示树)
父结点/双亲含有直接子结点的结点,是子结点的直接上层结点A是B、C、D、E、F、G的父结点(A直接包含这6个子结点)
子结点/孩子被父结点直接包含的结点,是父结点的直接下层结点B、C、D、E、F、G是A的子结点
结点的度结点拥有的直接子结点数量(仅统计 immediate child)A的度为6(有B、C、D、E、F、G共6个直接子结点)
树的度树中所有结点的度的最大值树的度为6(A的度最大,为6)
叶子结点度为0的结点(无任何直接子结点,是树的“最底层终端结点”)B、C、H、K、L、M、N、P、Q(这些结点没有子结点)
分支结点度不为0的结点(非叶子结点,可继续延伸子树)A、D、E、F、G、J(这些结点有直接子结点)
兄弟结点拥有相同父结点的结点B、C、D、E、F、G互为兄弟结点(它们的父结点都是A)
结点的层次从根开始计数,根为第1层,子结点为第2层,依此类推A在第1层;B、C在第2层;H、I在第3层;P、Q在第4层
树的高度/深度树中结点的最大层次(从根到最底层叶子的最长路径的层数)树的高度为4(最底层结点P、Q在第4层)
祖先根结点到该结点的路径上的所有结点P的祖先是A、E、J(路径:A→E→J→P)
子孙以该结点为根的子树中的所有结点(包括间接子结点)E的子孙是I、J、P、Q(E的子树包含这些结点)
森林m(m>0)棵互不相交的树的集合(多棵独立树的组合)若“以B为根的树”和“以C为根的树”相互独立,则它们组成森林

1.4 树的表示方法(孩子兄弟表示法)

树的存储需要同时保存“结点值”和“结点间的层次关系”,常用的是孩子兄弟表示法

结构定义

// 树的孩子兄弟表示法结点结构
typedef struct TreeNode {int data;                  // 结点存储的数据struct TreeNode* firstChild; // 指向该结点的“第一个子结点”(左起第一个)struct TreeNode* nextBrother; // 指向该结点的“下一个兄弟结点”(同一父结点的右侧兄弟)
} TreeNode;

在这里插入图片描述

为什么用孩子兄弟表示法?

  • 优点:只需两个指针(firstChildnextBrother),就能表示任意结构的树;且能将树“转化为二叉树”(把“兄弟关系”当作二叉树的“右子树”),后续可复用二叉树的操作逻辑。
  • 示例:若结点B有子结点E、F,且B的兄弟是C,则B->firstChild = EE->nextBrother = FB->nextBrother = C

1.5 树的实际应用场景

  • 文件系统:根目录(根结点)→ 文件夹(分支结点)→ 文件(叶子结点);
  • 组织架构:CEO(根结点)→ 部门总监(分支结点)→ 员工(叶子结点);
  • 数据库索引:B树、B+树(基于树结构实现高效查询)。

二、二叉树的概念与特性

树的结构灵活但复杂,而二叉树是树中最简单、最常用的类型——它限制了结点的度不超过2,大大降低了操作难度,且任意树都能转换为二叉树。

2.1 为什么重点研究二叉树?

在这里插入图片描述

既然树能表示任意层级关系,为什么还要专门学二叉树?答案是**“trade-off(权衡)”**:

  • 树的结点度可以是任意值(如一个结点有100个子结点),导致操作逻辑(如遍历、插入)非常复杂;
  • 二叉树限制“结点度≤2”,且子树有“左、右之分”(有序),操作逻辑统一,易于实现;
  • 关键:任意树都能通过“孩子兄弟表示法”转换为二叉树,学会二叉树就相当于掌握了所有树的核心操作。

2.2 二叉树的定义与核心特点

二叉树是结点的有限集合,满足:

  1. 集合为空(空二叉树);
  2. 由一个根结点 + 一棵“左子树” + 一棵“右子树”组成,且左、右子树均为二叉树;
  3. 核心约束
    • 结点的度≤2(最多有2个孩子:左孩子、右孩子);
    • 子树有“左右次序”(左子树和右子树颠倒后,是不同的二叉树)。

在这里插入图片描述

2.3 特殊的二叉树

二叉树中最常用的两种特殊类型是“满二叉树”和“完全二叉树”,后者是堆的基础。

2.3.1 满二叉树

在这里插入图片描述

  • 定义:每一层的结点数都达到最大值的二叉树(即第k层有2^(k-1)个结点)。
  • 公式:若满二叉树的层数为h,则总结点数为2^h - 1(等比数列求和:1+2+4+…+2^(h-1) = 2^h -1)。
  • 示例:h=3的满二叉树,总结点数=2^3 -1=7(第1层1个,第2层2个,第3层4个)。

2.3.2 完全二叉树

在这里插入图片描述

  • 定义:深度为h、有n个结点的二叉树,若其结点与“深度为h的满二叉树”中编号1~n的结点一一对应(编号从根开始,从上到下、从左到右),则为完全二叉树。
  • 核心特点:
    • 叶子结点只能出现在最后两层
    • 最后一层的叶子结点必须从左到右连续排列(不能有“左边空、右边有”的情况);
    • 满二叉树是“特殊的完全二叉树”(n=2^h -1时,完全二叉树就是满二叉树)。
关键区别:满二叉树要求“每一层都满”,完全二叉树只要求“最后一层左连续”——完全二叉树更灵活,且适合用数组存储(无空间浪费)。

2.4 二叉树的重要性质

以下性质基于“根结点层数为1”的规则,是后续堆操作的数学基础:

  1. 第i层最多结点数:若根为第1层,则第i层最多有2^(i-1)个结点(如第1层1=2^0 ,第2层2=2^1, 第3层4=2^2);
  2. 深度h的最大结点数:深度为h的二叉树,最多有2^h -1个结点(即满二叉树的结点数公式);
  3. 叶子结点与分支结点关系:对任意非空二叉树,若叶子结点数为n0,度为2的结点数为n2,则必有n0 = n2 + 1(推导:总边数=总结点数-1,且边数= n11 + n22,总结点数= n0 + n1 + n2,联立得n0 = n2 +1);
  4. 完全二叉树的父/子索引关系:若完全二叉树用数组存储(索引从0开始),则序号为i的结点:
    • 父结点序号:(i-1)/2(整数除法,如i=1的父结点是0,i=2的父结点是0);
    • 左孩子序号:2*i + 1(若2*i+1 < 总结点数,则存在左孩子);
    • 右孩子序号:2*i + 2(若2*i+2 < 总结点数,则存在右孩子)。

三、二叉树的存储结构

二叉树有两种存储方式,分别对应不同的应用场景:

3.1 顺序存储(数组存储)

原理

数组存储二叉树的结点,结点的位置(索引)由其在完全二叉树中的编号决定(参考“完全二叉树的父/子索引关系”)。

  • 适合场景:完全二叉树(无空间浪费);
  • 不适合场景:非完全二叉树(空结点需占用数组位置,空间利用率低)。

示例(完全二叉树的顺序存储)

若完全二叉树结点为[A, B, C, D, E, F](根为A,左子树B、D、E,右子树C、F),数组存储如下:
在这里插入图片描述

数组索引012345
结点值ABCDEF
  • A(0)的左孩子是B(1=20+1),右孩子是C(2=20+2);
  • B(1)的左孩子是D(3=21+1),右孩子是E(4=21+2);
  • C(2)的左孩子是F(5=22+1),右孩子不存在(22+2=6 ≥ 总结点数6)。

3.2 链式存储(二叉链)

原理

链表存储二叉树,每个结点包含“数据域”和两个“指针域”(分别指向左孩子和右孩子),称为“二叉链”。

  • 适合场景:所有二叉树(尤其是非完全二叉树,无空间浪费,灵活);
  • 缺点:无法像数组那样随机访问,需通过指针遍历。

结构定义(C语言)

// 二叉树的链式存储(二叉链)
typedef struct BinaryTreeNode {int data;                          // 结点数据struct BinaryTreeNode* leftChild;  // 指向左孩子的指针struct BinaryTreeNode* rightChild; // 指向右孩子的指针
} BTNode;

示例(二叉链结构)

对于结点[A, B, C, D](A的左是B,右是C;B的左是D),二叉链的结构为:

A
├─ leftChild → B
│  ├─ leftChild → D
│  └─ rightChild → NULL
└─ rightChild → C├─ leftChild → NULL└─ rightChild → NULL

四、堆的概念与基础实现

堆是特殊的完全二叉树,也是二叉树顺序存储的典型应用(如优先队列、堆排序)

4.1 堆是什么?

我们已经有了完全二叉树,为什么还要定义“堆”?因为堆在“快速获取最大值/最小值”场景中效率极高——堆的根结点永远是“最大值(大堆)”或“最小值(小堆)”,无需遍历整个树就能获取极值。

4.2 堆的定义与核心条件

堆是满足以下两个条件的完全二叉树:

  1. 结构条件:堆必须是一棵完全二叉树(保证可以用数组顺序存储,无空间浪费);
  2. 值条件(堆序性)
    • 大堆:每个父结点的值 ≥ 其左右子结点的值(根是最大值);
    • 小堆:每个父结点的值 ≤ 其左右子结点的值(根是最小值)。

在这里插入图片描述

4.3 堆的存储(数组顺序存储)

堆是完全二叉树,因此用数组存储最高效(无需额外指针,仅通过索引即可推导父子关系)。存储规则与完全二叉树一致,核心依赖“父、左孩子、右孩子的索引推导”:

  • 数组索引从0开始;
  • 对于序号为i的结点,可通过公式快速找到其亲属结点:
    • 父结点索引:(i - 1) / 2(整数除法,向下取整);
    • 左孩子索引:2 * i + 1(若计算结果 < 堆的元素个数,则左孩子存在);
    • 右孩子索引:2 * i + 2(若计算结果 < 堆的元素个数,则右孩子存在)。

示例1:大根堆的数组存储

在这里插入图片描述

大根堆的逻辑结构:根结点为70,左子结点30,右子结点5630的左子结点25、右子结点1556的右子结点10

数组存储结构[70, 30, 56, 25, 15, 10](数组索引0~5对应元素),各结点的亲属关系推导如下:

数组索引结点值父结点(索引/值)左孩子(索引/值)右孩子(索引/值)
070无(根结点)2*0+1=1 / 302*0+2=2 / 56
130(1-1)/2=0 / 702*1+1=3 / 252*1+2=4 / 15
256(2-1)/2=0 / 702*2+1=5 / 10无(2*2+2=6 ≥ 元素个数6
325(3-1)/2=1 / 30无(2*3+1=7 ≥ 6无(2*3+2=8 ≥ 6
415(4-1)/2=1 / 30无(2*4+1=9 ≥ 6无(2*4+2=10 ≥ 6
510(5-1)/2=2 / 56无(2*5+1=11 ≥ 6无(2*5+2=12 ≥ 6

示例2:小根堆的数组存储

在这里插入图片描述

小根堆的逻辑结构:根结点为10,左子结点15,右子结点5615的左子结点25、右子结点3056的右子结点70

数组存储结构[10, 15, 56, 25, 30, 70](数组索引0~5对应元素),亲属关系推导更能体现“小根堆父结点≤子结点”的特性:

数组索引结点值父结点(索引/值)左孩子(索引/值)右孩子(索引/值)
010无(根结点)2*0+1=1 / 152*0+2=2 / 56
115(1-1)/2=0 / 102*1+1=3 / 252*1+2=4 / 30
256(2-1)/2=0 / 102*2+1=5 / 70无(2*2+2=6 ≥ 6
325(3-1)/2=1 / 15无(2*3+1=7 ≥ 6无(2*3+2=8 ≥ 6
430(4-1)/2=1 / 15无(2*4+1=9 ≥ 6无(2*4+2=10 ≥ 6
570(5-1)/2=2 / 56无(2*5+1=11 ≥ 6无(2*5+2=12 ≥ 6

我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343
我的C语言数据结构专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_12830540.html?spm=1001.2014.3001.5482

非常感谢您的阅读,喜欢的话记得三连哦

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/921426.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/921426.shtml
英文地址,请注明出处:http://en.pswp.cn/news/921426.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STAR-CCM+|雷诺数回顾

【1】引言 前序已经学习了K-epsilon湍流模型溯源的基础知识&#xff0c;今天再学习一些更为基础的知识&#xff0c;回顾一下雷诺数ReReRe。 【2】雷诺数定义 雷诺数公式为&#xff1a; ReρvDμRe\frac{\rho vD}{\mu}ReμρvD​ 式中&#xff0c; ρ\rhoρ——流体密度&…

Java中的死锁

锁的合理使用能够保证共享数据的安全性&#xff0c;但是 使用不当也会可能引起死锁。1. 死锁概念 死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力干涉那它们都将无法推进下去&#xff0c;如果系统资源充足&#xff0c;进程的资源请求…

基于STM32F103C8T6的智能家居健康环境监测系统

项目开发背景 随着城市化进程加速和居民生活水平提升&#xff0c;人们对家居环境健康与安全的需求日益增强。现代住宅常因装修材料、密闭空间及外部污染导致甲醛超标、PM2.5浓度升高、温湿度失衡等问题&#xff0c;长期暴露此类环境中易引发呼吸道疾病、过敏反应等健康隐患。传…

2025职场进阶:B端产品经理必备的计算机专业技能精要

当前企业级服务市场竞争日益激烈&#xff0c;2025年的B端产品经理不仅需要深厚的行业认知&#xff0c;还必须具备扎实的计算机专业技能&#xff0c;才能设计出真正符合技术趋势与业务需求的企业级产品。而其中&#xff0c;人工智能技术已经成为B端产品不可或缺的组成部分&#…

有效三角形的个数(数组单调性)

目录 一&#xff1a;题目链接 二&#xff1a;题目思路 三&#xff1a;代码实现 一&#xff1a;题目链接 题目的要求是找出当前数组能组成三角形三元组的个数。 二&#xff1a;题目思路 有一种暴力枚举解法&#xff0c;利用三层 for 循环来一一枚举三元组的情况&#xff0c;如…

Rust在医疗系统中的应用:安全、性能与合规性实践(上)

Rust在医疗系统中的应用:安全、性能与合规性实践 摘要 医疗系统对软件安全与性能存在严苛双重需求,既需抵御内存漏洞、数据加密风险等安全威胁(如历史医疗设备因软件问题召回案例所示),又需满足电子健康记录(EHR)系统、医学影像处理等高并发数据场景的性能要求,同时需…

读写锁 shared_mutex 共享互斥量介绍

文章目录读数据对数据没有影响&#xff0c;为什么还需要shared_mutex1. 保证读取数据的“一致性”和“时效性”2. 协调“读”与“写”的竞争关系总结好的&#xff0c;我们来详细介绍 C17 中的 std::shared_mutex&#xff08;共享互斥量&#xff0c;俗称读写锁&#xff09;的使用…

Nestjs框架: 基于装饰器与Guards的完成RBAC权限系统设计与实现

概述 在现代权限管理系统中&#xff0c;RBAC&#xff08;基于角色的访问控制&#xff09;是广泛采用的一种模型RBAC 核心思想是通过角色来管理用户权限通过角色绑定用户、资源和权限&#xff0c;实现细粒度的访问控制为了实现这一目标&#xff0c;我们需要在数据库中设计合理的…

机器学习如何精准预测高值

一、概念理解“机器学习对于高值的预测保守”&#xff0c;这是建模里很常见的现象&#xff0c;尤其在生态、气候、遥感这类数据分布高度偏斜的场景。通常可以从以下几个角度理解&#xff1a;1. 数据分布与样本稀缺在训练集里&#xff0c;高值样本往往非常少&#xff0c;远低于中…

蜂窝物联网模组:智能门禁产品上的关键部件

随着物联网技术的快速发展&#xff0c;蜂窝物联网模组正逐步成为智能门禁系统的关键通信组件。蜂窝模组凭借其广覆盖、高可靠性和低功耗特性&#xff0c;正从传统门禁系统的补充角色转变为智能门禁的核心通信组件&#xff0c;尤其在智慧社区、商业楼宇和政府机构等场景中展现出…

[光学原理与应用-417]:非线性光学 - 线性光学(不引发频率的变化)与非线性光学(引发频率变化)的异同

一、定义与物理机制&#xff1a;线性响应 vs 非线性响应线性光学定义&#xff1a;光与物质相互作用时&#xff0c;介质的极化强度与入射光电场强度呈线性关系&#xff08;Pϵ0​χ(1)E&#xff09;&#xff0c;输出光强与输入光强成正比&#xff08;Iout​∝Iin​&#xff09;-…

深入探讨AI在三大核心测试场景中的应用

随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;软件测试领域正经历深刻变革。传统手动测试和基于规则的自动化测试已难以应对日益复杂的系统架构与海量用户行为。AI测试通过引入机器学习、自然语言处理、计算机视觉等技术&#xff0c;显著提升了测试效率、…

[linux仓库]性能加速的隐形引擎:深度解析Linux文件IO中的缓冲区奥秘

&#x1f31f; 各位看官好&#xff0c;我是egoist2023&#xff01; &#x1f30d; Linux Linux is not Unix &#xff01; &#x1f680; 今天来学习C语言缓冲区和内核缓存区的区别以及缓存类型。 &#x1f44d; 如果觉得这篇文章有帮助&#xff0c;欢迎您一键三连&#xff0c…

一、计算机的数据存储

计算机的世界只有0和1。 1.1 进制 十进制整数->二进制整数&#xff1a;除2倒取余二进制->十进制&#xff1a;权值相加法 结论&#xff1a;1位8进制值 3位二进制值&#xff0c;1位十六进制值 4位二进制值 public class JinZhiDemo {public static void main(String[]…

SpringBoot集成XXL-JOB保姆教程

第一步&#xff1a; 下载xxl-job源码到本地&#xff0c;地址如下&#xff1a; xxl-job: 一个分布式任务调度平台&#xff0c;其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线&#xff0c;开箱即用。 第二步&#xff1a; 创建…

Debezium日常分享系列之:Debezium 3.2.2.Final发布

Debezium日常分享系列之&#xff1a;Debezium 3.2.2.Final发布Debezium CoreConnector启动时出现难以理解的错误临时阻塞快照失败可能导致数据丢失的问题修复Debezium for OracleDebezium CoreConnector 启动时出现难以理解的错误 我们解决了一个问题&#xff0c;即连接器会因…

Zoom AI 技术架构研究:联合式方法与多模态集成

一、研究背景与概述 在当今数字化转型加速的背景下,人工智能技术正深刻改变企业协作与沟通方式。作为全球领先的视频会议平台,Zoom 已从单纯的通信工具转型为全面的生产力平台,而其 AI 技术架构是这一转变的核心驱动力。本报告将深入分析 Zoom 的 AI 技术架构,特别是其创新…

排序-快速排序 O(n log n)

快排&#xff1a;1、设定一个中间值 q[ lr >>1 ] , 让左右区间来比较2、左边通过 i 依次比较&#xff0c;如果比这个中间值小&#xff0c;就继续 , 直到不符合3、右边通过 j-- 依次比较&#xff0c;如果比这个中间值大&#xff0c;就继续 &#xff0c;直到不符合4、两边…

【Proteus仿真】定时器控制系列仿真——LED小灯闪烁/流水灯/LED灯带控制/LED小灯实现二进制

目录 0案例视频效果展示 0.1例子1&#xff1a;基于AT89C51单片机的定时器控制小灯闪烁 0.2例子2&#xff1a;基于AT89C51单片机的定时器T0流水灯 0.3例子3&#xff1a;基于AT89C51单片机的定时器控制LED灯带 0.4例子4&#xff1a;基于AT89C51单片机的定时器控制LED闪烁 0…

进阶向:密码生成与管理工具

密码生成与管理工具&#xff1a;从零开始的完全指南在现代数字生活中&#xff0c;密码是保护个人信息和账户安全的第一道防线。随着网络服务的普及&#xff0c;每个人平均需要管理数十个不同账户的密码。一个强大且独特的密码通常应包含12个以上字符&#xff0c;混合大小写字母…