目录
树的基础知识
树的定义
树(Tree)是n (n ≥ 0)个结点的有限集。
若n=0,称为空树;
若n> 0,则它满足如下两个条件:
(1)有且仅有一个特定的称为根(Root)的结点;
(2)其余结点可分为m(m ≥ 0)个互不相交的有限集T1,T2,T3,...,Tm,其中每一个集合本身又是一棵树,并称为根的子树(SubTree)。
树的基本术语
结合该图理解以下术语:
根结点:非空树中无前驱结点的结点。 {例:上图中A结点}
结点的度:结点拥有的子树数。{例:上图A结点拥有三个子树所以度数为3}
树的度:树内各结点的度的最大值。{例:上图度的最大值为3,所以树的度为3}
非终端结点:度不为0的结点称为非终端结点或分支结点。{例:图中A、B、C、E等结点}
终端结点:度为0的结点称为终端结点或叶子。{例:图中K、L、M、J等结点}
内部结点:除了根结点外所有有分支的结点。{例:图中B、C、D、E等结点}
双亲和孩子:结点的子树的根称为该结点的孩子,该结点称为孩子的双亲。{例:E结点是K结点的双亲,L结点是E结点的孩子}
树的深度:树中节点的最大层次。{例:图中树一共四层,所以树的深度为4}
兄弟和堂兄弟:双亲在同一层的结点,双亲相同则是兄弟,双亲不同则是堂兄弟。{例:I结点和J结点是兄弟、G结点和H结点是堂兄弟}
结点的祖先:从根到该结点所经分支上的所有结点。{例:A、B、E结点是K结点的祖先}
结点的子孙:以某结点为根的子树中的任一结点。{例:D结点的子孙结点有H、M、I结点等}
森林:是m(m≥0)棵树互不相交的树的集合。把根结点删除树就变成了森林,给森林中的各子树加上一个双亲结点,森林就变成了树。(树一定是森林,森林不一定是树){例:去掉根结点A,有三个树T1、T2、T3构成了一个森林}
有序树:树中结点的各个子树从左至右有次序(最左边的为第一个孩子)。{例:结点按照一定标准有序排列则是有序树}
无序树:树中结点的各子树无次序。{例:不满足上述有序树的标准的都是无序树}
树型结构和线性结构的比较
线性结构 | 树型结构 |
第一个数据元素(无前驱) | 根结点(只有一个、无双亲) |
最后一个数据元素(无后继) | 叶子结点(可以有多个、无孩子) |
其他数据元素 (一个前驱、一个后继、一对一) | 其它结点——中间结点 (一个双亲、多个孩子、一对多) |
二叉树的基础知识
二叉树的定义
二叉树是n (n ≥ 0)个结点的有限集,它或者是空集(n = 0),或者由一个根结点及两棵互不相交的分别称作这个根的左子树和右子树的二叉树组成。
二叉树的特点
1、每个结点最多有俩孩子(二叉树中不存在度大于2的结点)。
2、子树有左右之分,其次序不能颠倒。
3、二叉树可以是空集合,根可以有空的左子树或空的右子树。
二叉树与树的区别
首先值得声明的一点是:二叉树不是树的特殊情况,他们是两个概念。
二叉树结点的子树要区分左子树和右子树,即使只有一棵子树也要进行区分,说明它是左子树,还是右子树。
树当结点只有一个孩子时,就无须区分它是左还是右的次序。因此二者是不同的。这是二叉树与树的最主要的差别。
(也就是二叉树每个结点位置或者说次序都是固定的,可以是空,但是不可以说它没有位置,而树的结点位置是相对于别的结点来说的,没有别的结点时,它就无所谓左右了)
[注:虽然二叉树与树概念不同,但有关树的基本术语对于二叉树都适用。]
两种特殊形式的二叉树
- 满二叉树
- 完全二叉树
[ 注:在满二叉树中,从最后一个结点开始,连续去掉任意个结点,即是一棵完全二叉树。]
二叉树的性质
性质1:在二叉树的第 i 层上至多有个结点(i ≥ 1)。
(PS:第 i 层上最少有1个结点)
性质2:深度为 k 的二叉树至多有个结点(K ≥ 1)。
(PS:深度为 k 时至少有 k 个结点)
性质3:对于任何一颗二叉树T,如果其叶子树为,度为2的结点数为,则。
性质4:具有n个结点的完全二叉树的深度为。
性质5: 如果对一棵树有n个结点的完全二叉树(深度为)的结点按层序编号(从第1层到第层,每层从左到右),则对任一结点 i (1 i n),有:
性质5表明了完全二叉树中双亲结点编号与孩子结点编号之间的关系。
二叉树的存储结构
- 二叉树的顺序存储
二叉树顺序存储实现:
按照满二叉树的结点层次编号,依次存放在二叉树中的数据元素。
二叉树顺序存储表示:
#define MAXTSIZE 100
typedef TElemType SqBiTree[MAXTSIZE];
SqBiTree bt;
二叉树的顺序存储缺点:
最坏情况:深度为 k 的且只有 k 个结点的单支树需要长度为的一维数组。
二叉树的顺序存储特点:
结点间关系蕴含在其存储位置中,浪费空间,适用于满二叉树和完全二叉树。
- 二叉树的链式存储
二叉树的链式存储表示:
typedef struct BiTNode{
TElemType data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
引入问题: 在n个结点的二叉链表中,有n + 1个空指针域。
分析:必有2n个链域。除根结点外,每个结点有且仅有一个双亲,所以只会有n - 1个结点外的链域存放指针,指向非空子女结点。[空指针数目 = 2n - ( n -1 ) = n + 1]
遍历二叉树
遍历定义——顺着某一条搜索路径巡访二叉树中的结点,使得每个结点均被访问一-次,而且仅被访问一次(又称周游)。
遍历目的——得到树中所有结点的一个线性排列。
遍历用途——它是树结构插入、删除、修改、查找和排序运算的前提,是二叉树一切运算的基础和核心。
遍历的类别
遍历二叉树可以分为先序、中序、后序遍历,其具体步骤如下:
例如:
值得一提的是还有一种是层次遍历,是按照树的层次从上到下、从左到右依次遍历。
有关遍历算法的代码实现可以查看该专栏内的其他文章。
链接:二叉树的基本操作代码实现