前言
在计算机科学中,树是一种非常重要的非线性数据结构,它以层次化的方式组织数据,广泛应用于文件系统、编译原理、数据库索引等领域。而堆作为一种特殊的完全二叉树,不仅实现了高效的优先队列,更是堆排序算法的核心。本文将带你从树的基础概念出发,逐步深入堆的实现,并最终掌握堆排序的原理与代码编写。
一、树的概念
1.1 树的定义
树(Tree)是由 n(n≥0)个有限结点组成的一个具有层次关系的集合。当 n=0 时,称为空树。在任意一棵非空树中:
- 有且仅有一个特定的结点称为根结点,根结点没有前驱结点。
- 除根结点外,其余结点可以分成 M(M>0)个互不相交的有限集合 T₁、T₂、...、Tₘ,其中每一个集合本身又是一棵树,称为根结点的子树。
树的定义是递归的:树由根和若干互不相交的子树构成,而子树本身也是一棵树。
1.2 树的相关术语
- 结点的度:一个结点拥有的子树个数。
- 叶结点(终端结点):度为 0 的结点。
- 分支结点(非终端结点):度不为 0 的结点。
- 父结点与子结点:若结点 A 有孩子 B,则 A 是 B 的父结点,B 是 A 的子结点。
- 兄弟结点:具有相同父结点的结点。
- 树的度:树中所有结点的度的最大值。
- 结点的层次:从根开始定义,根为第 1 层,根的子结点为第 2 层,以此类推。
- 树的高度(深度):树中结点的最大层次。
- 森林:由 m(m≥0)棵互不相交的树组成的集合。
1.3 树的表示
在实际编程中,我们需要用某种数据结构来存储树。树有多种表示方法,如双亲表示法、孩子表示法、孩子双亲表示法、孩子兄弟表示法等。最常用的是孩子兄弟表示法(也称为左孩子右兄弟表示法)。这种表示法可以将任意一棵树转化为二叉树的形式,从而方便地使用二叉树的算法进行处理。
孩子兄弟表示法的结点结构如下:
typedef int DataType;
struct Node {
struct Node* firstChild; // 指向第一个孩子结点
struct Node* pNextBrother; // 指向下一个兄弟结点
DataType data; // 结点中的数据域
};
1.4 树在实际中的应用
树结构在计算机中应用广泛,最典型的例子就是文件系统的目录树结构。根目录类似于树的根结点,子目录和文件则对应分支结点和叶结点。通过树形结构,我们可以高效地组织和管理文件。
二、二叉树概念及结构
2.1 二叉树的定义
二叉树(Binary Tree)是每个结点最多有两个子树的树结构,并且子树有左右之分,次序不能颠倒。二叉树的定义也是递归的:
- 要么为空树;
- 要么由一个根结点加上两棵分别称为左子树和右子树的二叉树组成。


