目录
一. 树
1.1 树的概念及结构
1.2 树和树的节点的相关概念
1.3 定义树的四种方式
1.3.1 说明了树的度为N
1.3.2 采用顺序表的方式存储子节点
1.3.3 采用结构体数组进行存储
1.3.4 左孩子右兄弟表示法(最优)
二. 二叉树
2.1 二叉树的概念及结构
2.2 两种特殊的二叉树
2.3 二叉树的性质
2.4 二叉树的存储
2.4.1 顺序存储
2.4.2 链式存储
一. 树
1.1 树的概念及结构
- 树是一种非线性结构,它由n(n>=0)个有限节点组成一个具有层次关系的集合。把它叫做数是因为它的逻辑结构(见图1.1)像一颗倒挂的树,根朝上,叶朝下。
- 树有一个根节点,根节点没有前驱结点。
- 除根节点外,其余节点被分为M(M>0)个互不相交的集合T1、T2、...、Tm,其中每一个集合Ti又是一颗与树类似的子树,每颗子树的根节点只有一个前驱,可以有多个后驱。
- 任何树都可以被分为根和子树,详见图1.2。
1.2 树和树的节点的相关概念
- 节点的度:一个节点含有的子树的个数,如:图1.1中A节点的度为3。
- 叶子节点(终端节点):度为0的节点,如:图1.1中J、K、L为叶子节点。
- 分支节点(非终端节点):度不为0的节点。
- 父亲节点(双亲节点):若一个节点含有子节点,则这个节点为其子节点的父亲节点,如:图1.1中A为B、C、D的父亲节点。
- 子节点:一个节点含有的子树的根节点为该节点的子节点,如:图1.1中E、F为B的子节点。
- 兄弟节点:具有相同父节点的节点称为兄弟节点,如:图1.1中B、C、D互为兄弟节点。
- 树的度:一棵树中,最大节点的度称为树的度,如:图1.1所示树的度为3。
- 节点的层次:从根节点开始定义,根为第1层,根的子节点为第2层,以此类推。如:图1.1中节点A的层次为1,节点B的层次为2,节点J的层次为4。
- 树的高度(深度):树中节点的最大层次,如:图1.1中树的高度为4。
- 堂兄弟节点:父节点在同一层次的节点,如:图1.1中F、G互为堂兄弟节点。
- 子孙:以某节点为根的子树中任意节点都为该节点的子孙,如:图1.1中所有节点都为A的子孙。
- 节点的祖先:从根到该节点所经分支上的所有节点均为该节点的祖先,如:图1.1中A为所有节点的祖先,A、C、G均为K、L的祖先。
- 森林:由m(m>0)颗数构成的集合称为森林。
1.3 定义树的四种方式
1.3.1 说明了树的度为N
struct TreeNode
{
int data; //树节点存储的数据
struct TreeNode[N]; //数的子节点(子节点个数一定<=N)
}
问题:
- 由于可能存在多个节点的度小于N,会造成空间浪费。
- 可能不知道树的度是多少
1.3.2 采用顺序表的方式存储子节点
typedef struct TreeNode* SLDataType; //顺序表存储树节点数据类型
typedef struct SeqList //定义顺序表来存储子节点地址
{
SLDataType* a; //指向树的子节点的指针
int sz; //子节点个数
}SeqList;
struct TreeNode
{
int data; //节点数据
SeqList s; //存储子节点地址的顺序表
};
问题:结构相对复杂。
1.3.3 采用结构体数组进行存储
typedef struct TreeNode //树的节点
{
int parent; //父亲节点在数组中的下标
int data; //节点中存储的数据
}TN;
TN tree[...] = {... ...}; //存储树节点结构体的数组
问题:
- 结构相对复杂。
- 只能找到一个节点的父亲节点,很难找到一个节点的子节点。
1.3.4 左孩子右兄弟表示法(最优)
上述三种表示树结构的方法各有各的问题,左孩子右兄弟表示法是表示一般树形结构的最优方法。
typedef int DataType;
struct TreeNode
{
struct TreeNode* _firstChild; //指向其左侧第一个子节点
struct TreeNode* _pnextBrother; //指向其1右侧第一个兄弟节点
DataType data;
};
二. 二叉树
2.1 二叉树的概念及结构
一颗二叉树是节点的一个有限集合,该集合:
- 可能为空。
- 由一个根节点加上两颗分别称为左子树和右子树的二叉树组成。
通俗理解,二叉树就是度最大为2的树,二叉树的典型结构图见图2.1。
二叉树有以下结构特点:
- 二叉树不存在度大于2的节点。
- 二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树。
2.2 两种特殊的二叉树
满二叉树
- 如果一个二叉树每层的节点数都达到了最大值(除了最后一层节点外,所有节点的度均为2),那么它就是满二叉树.满二叉树所有叶子节点都在最后一层,所有分支节点都有两个子节点。
- 如果一个二叉树的层数为,节点数为,那么它就是满二叉树。
完全二叉树
- 完全二叉树是从满二叉树中延伸出来的,是一种效率很高的数据结构。
- 完全二叉树的前N-1层节点数均达到了最大值,最后一层可能不满,但从左到右是连续的。
- 满二叉树是一种特殊的完全二叉树。
2.3 二叉树的性质
- 若规定根节点的层数为1,那么一颗非空二叉树第层的节点数为。
- 高度为的二叉树含有的最大节点数为。
- 对于任何一颗二叉树,若度为0的节点数为,度为2的节点个数为,有:
- 具有n个节点的满二叉树的深度为:
2.4 二叉树的存储
二叉树的存储有两种方式:顺序存储和链式存储
2.4.1 顺序存储
二叉树的顺序存储即使用数组来存储,一般只适用于完全二叉树。对于非完全二叉树,也可以使用顺序存储,但这会造成空间浪费。
特性:
- 假设parent是数组中父亲节点的下标,则其左孩子节点和右孩子节点在数组中的下标可以表示为:leftchild = 2 × parent + 1、rightchild = 2 × parent + 2。
- 无论左孩子节点还是右孩子节点,若某个节点的有父亲节点,则:parent = (child - 1) / 2。
2.4.2 链式存储
- 用链式结构存储二叉树可分为二叉链表存储和三叉链表存储。
- 二叉链表包含两个指针,分别指向左孩子节点和右孩子节点。
- 三叉链表包含三个指针,分别指向左孩子节点、父亲节点和右孩子节点。