一、树型结构:
元素之间存在一对多关系的数据结构,适合存储具有层次关系的数据模型,如:文件树、组织关系、族谱。
二、树的相关术语:
根结点: 树的最顶层结点,一棵树最多只有一个根结点。
双亲结点、父结点: 结点的上一层结点,一个结点只有唯一一个双亲结点。
子结点: 结点的下层结点,可以有若干个。
叶子节点: 没有子结点的结点。
树的高度: 树的层数
树的密度: 树的结点数量
三、树的种类:
普通树: 只有一个双亲结点,子结点的数量任意。
二叉树: 一个结点最多有两个孩子。
B树: 多路平衡查找树,
多路: 最多有M个子结点
平衡: 所有子树的高度相差不超过1
查找: 所有结点是有序的
四、二叉树的种类:
性质1: 在二叉树的第 i 层上至多有2^(i-1)个结点
性质2: 深度为k的二叉树至多有2^k-1个结点
性质3: 对任何一颗二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1。
n0+n1+n2 = n
n1+n2*2 = n-1
性质4: 具有n个结点的完全二叉树的深度为[log(n)]+1([x]表示不大于x的最大整数)
性质5: 如果对一棵有n个结点的完全二叉树(其深度为[log(n)]+1)的结点按层序编号
(从第1层到第[log(n)]+1层,每层从左到右),对任一结点i(1<=i<=n)有:
(1).如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲是结点[i/2]
(2).如果2i>n,则结点i无左孩子(结点i为叶子结点);否则其左孩子是结点2i
(3).如果2i+1>n,则结点i无右孩子;否则其右孩子是结点2i+1
满二叉树: 除最后一层无任何子节点外,每一层上的所有结点都有两个子结点的二叉树,
每层的结点数量是:2^(n-1), 总结点数是:2^n-1。
完全二叉树:
除了最后一层外的所有层的结点数是:2^(n-1)。
最后一层的结点按照从左到右的顺序排列。
有序二叉树:
左子结点比双亲结点小,右子结点比双亲结点大,所有结点都遵循该规则。
线索二叉树:
给普通二叉树结点,增加上线索,使用它能够以循环的方式遍历,提高遍历速度。
哈夫曼树: 带权重的二叉树。
平衡二叉树: 左右子树高度相差不超过1。
红黑树: 接近平衡的二叉树,伪平衡二叉树。
堆:
大根堆:双亲结点比左右子结点都大。
小根堆:双亲结点比左右子结点都小。
五、树的存储
二叉树的链式存储:
每个结点(元素)由三部分组成:
值
左子树指针
右子树指针
优点:能很清晰的表示树的结构,对内存的要求低,节约内存。
缺点:只能逐级访问,递归遍历,可能产生内存碎片。
二叉树的顺序存储:
注意:需要把普通二叉树补全为完全二叉树。
[] [#][] [#][#][][] [][][][][][][]
前提:节点的下标从1开始排列
i/2 = 父节点下标
i2 = 左子节点下标
i2+1 = 右子节点下标
优点:创建树方便,计算高度、密度速度快,使用的整块内存不易产生内存碎片。
缺点:对内存的要求高,当树比较稀疏时,对内存浪费极高,转换成完全二叉树时麻烦。
有序二叉树:
左右子树与根结点的关系必须满足:左 < 根 <= 右
当采用中序遍历时有序二叉树的遍历结果是从小到大的。
当它结点均匀、平衡,查找效率接近二分查找,
如果不均匀且呈单支状分布它查找的效率接近链表。
注意:创建有序二叉树的目的是为了能够借助它的二分查找特性,快速查找数据。
线索二叉树:
当结点的右子树为空时,让它指向即将要访问的下一个结点,然后就可以使用循环来遍历这棵树,
提高遍历的效率。
堆:
堆是一种特殊的二叉树,它对结点的位置不做要求,所以一般以完全二树或满二叉来存储它。
哈夫曼树:
结点由数据+权重(数据出现的概率)组成,权重越高结点的层数越小。
创建过程:
1、把所有的数据和权重创建成结点(子树),也被称为创建森林。
2、然后根据权重排序,把权重最小的两棵子树合并形成新的子树,并成为它的左右子树。
3、再把新合并的子树与现在的森林进行排序,重复2上步骤,直到没有子树。
4、记录每个带数据的结点,从根据结点访问的路径,生成哈夫曼编码,由0和1组成,
0表示走了左子树,1表示走了右子树。
5、在之后存储数据时,用它的哈夫曼编码共代替数据,达到压缩数据的目的。
6、根据哈夫曼编码,从哈夫曼树中找到对应数据的过程叫解压数据。
平衡二叉树:
平衡二叉树(AVL)首先是一棵有序二叉树,为了解决有序二叉树不均匀导致查询速度过低,
而调整它左右平衡,使有序二叉树以最快的速度查询数据。
六、二叉树的遍历:
A
/ \
B C
/ / \
D E F
/ \ \
G H J
/
I
ABCD#EFGH###J####I
前序:根 左 右
第一个元素为根结点
A B D G H I C E J F
A B D G # # H I # # # # C E # J # # F # #
中序:左 根 右
最后一元素为根结点
G D I H B A E J C F
GDIHBAEJCF
后序:左 右 根
根结点左边的都是左子树,根结点右边的都是右子树。
G I H D B J E F C A
注意:所有子树都要遵循规则,要把每个结点当作一棵子树看待。
1、根据二叉树写出前、中、后遍历顺序。
2、根据 前序+中序 中序+后序 还原二叉树
G D I H B A E J C F 中
G I H D B J E F C A 后
1、根据后序确定根结点
2、根中序和根确定左右子树的数量
3、然后根据左右子树的数量确定,左右子树的后序
4、再使用同样的方法构建左右子树
G D I H B E J C F
G I H D B J E F C