二叉树的定义和基本术语
二叉树是n个数据元素的有限集,它或为空集(n=0),或者含有唯一的称为根的元素,且其余元素分别分成两个互不相交的子集,每个子集自身也是一颗二叉树,分别称为根的左子树和右子树。集合为空的二叉树简称为空树,二叉树中的元素也成为结点。
二叉树的左子树和右子树是两棵互不相交的二叉树,因此二叉树上除根之外的任何结点,不可能同时在两棵子树中出现。二叉树上每个结点至多只有两颗子树,并且有左右之分,其次序不能任意颠倒。
下面接收一些名词,如上图,2是1的左孩子,3是1的右孩子;1是2和3的父亲;根节点没有父亲,两个结点的父亲为同一结点则这两个结点为兄弟,2和3是兄弟,5和6不是兄弟但可以称之为堂兄弟,因为他们各自的父亲是兄弟;1为根的二叉树中所有的结点均为1的子孙。
左右子树均为空的结点称为叶子结点,所有非叶子结点称之为分支结点。结点的子树个数称之为结点的度;叶子结点的度为0,二叉树中结点的度数最大为2。结点在二叉树中的层次约定为:跟结点的层次为1,根节点的孩子层次为2,以此类推;二叉树中叶子结点的最大层次数定义为二叉树的深度。
特殊形态的二叉树分为:满二叉树和完全二叉树。如下图所示:
二叉树的基本操作包括:建立和销毁一棵二叉树,判断二叉树是否为空,返回二叉树的深度,由某个结点返回其双亲或者孩子等等;大致分为 插入类,查找类和删除类。
二叉树的基本性质
1,二叉树的第 i 层上至多有 个结点。
2,深度为 k 的二叉树至多有 个结点(k>=1)。
3,对任何一棵树,如果其终端结点数位 ,度为2的结点数为
,则
。
4,具有 n 个结点的完全二叉树的深度为 。
二叉树的存储结构
1,顺序存储结构
对于完全二叉树,只要从根起按层序存储即可。将完全二叉树上编号为 i 的结点元素存储在一维数组中下标为 i - 1 的分量中。对于一般二叉树,可以对应于完全二叉树进行存储,不存在的结点用零来代替。但是这样会造成极大的浪费,因此不合适。所以这种存储方法只适合完全二叉树(自然包括满二叉树)。其顺序存储结构定义如下:
const int MAXSIZE = 100; //暂定二叉树中结点数最大100
typedef struct {
int *data; //存储空间基址
int nodenum; //树中结点数
}SqBiTree;
2,链式存储表示
由于二叉树是一种非线性结构,因此采用链式存储结构比较合适,设计不同的结点结构可以构成不同形式的链表。表示二叉树的结点至少要包含三个域:数据域和分别指向左,右子树的指针域构成。有时为了方便找到结点的双亲,还可以增添一个指向其双亲结点的指针。利用这两种结点结构可以构成二叉树的二叉链表和三叉链表。链表的头指针指向二叉树的根结点。在不同的存储结构中,实现基本操作的方法不同。所以在应用程序中采用何种存储结构应该由二叉树的形态和进行的操作类型共同决定。如下为二叉树的二叉链表存储表示:
typedef struct BiTNode {
int data;
struct BiTNode *lchild, *rchild; //左右孩子指针
}BiTNode,*BiTree;
本笔记所依据的教材为严薇敏版的《数据结构及应用算法教程》
部分图片来源于华中师范大学云课堂
所有代码在Visual Studio 2017上均可正常运行
如有错误欢迎指出