数据结构树的相关知识点
本文主要是学习完树的相关知识后总结出来的一些理解,主要涉及到树,二叉树,平衡树和红黑树。
1. 树
1.1 树的基本概念
树是由结点或顶点和边组成的(可能是非线性的)且不存在着任何环的一种数据结构。
没有结点的树称为空(null或empty)树。一棵非空的树包括一个根结点,还(很可能)有
多个附加结点,所有结点构成一个多级分层结构。
1.2 树的特点
(1)每个节点有零个或者多个节点
(2)没有父节点的点称为根节点
(3)每一个非根节点有且只有一个父节点
(4)除了根节点外,每个子节点可以分为多个不想交的子树
1.3 相关名词理解
(1)节点:指树中的每一个元素
(2)节点的度:指节点拥有的子树的个数,二叉树的度不大于2
(3)叶子:度为0的节点,也称为终端节点
(4)高度:叶子节点的高度为0,根节点的高度最高
(5)层:根在第一层,以此类推
(6)父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点
(7)子节点:子节点是父节点的下一层节点
(8)节点的层次:从根节点开始,根节点为第一层,根的子节点为第二层,以此类推
(9)兄弟节点:拥有共同父节点的节点互称为兄弟节点
2.二叉树
2.1 什么是二叉树
二叉树是每个节点最多只有两个子树的树结构,二叉树要求左节点的值小于父节点,右节点的值大于父节点。
2.2 二叉树的五种基本形态
2.3 满二叉树、完全二叉树和霍夫曼树
(1)满二叉树:指深度为k且有2^k-1个结点的二叉树 。如图所示:
(2)完全二叉树:当二叉树的深度为h时,它的h层节点必须都是连续靠左并不可隔开的(满二叉树也符合),并且1~h-1层的结点数都达到最大个数(即1~h-1层为一个满二叉树)。
(3)霍夫曼树:每个节点要么没有子节点,要么有两个子节点
2.4 二叉树的遍历
二叉树主要有三种遍历方式:先序遍历、中序遍历、以及后序遍历
(1)先序遍历(根左右):先访问根节点,再访问根的左节点,最后访问根的右节点
(2)中序遍历(左根右):先访问左节点,再访问根节点,最后访问右节点。中序遍历可以用来排序
(3)后序遍历(左右根):先访问左节点,再访问右节点,最后访问根节点
3. 平衡二叉树
3.1 什么是平衡二叉树
平衡树,即平衡二叉树(Balanced Binary Tree),具有以下性质:它是一棵空树或它的左右两个子树的高
度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
3.2 为什么要用平衡二叉树
当遇到下图所示情况时,我们遍历该二叉树需要很多层,这个时候并不能节约遍历的时间。为了避免这种情况
发生,我们希望有一种算法,将我们的不平衡二叉排序树转化为平衡二叉排序树。这样就可以让我们的二叉排序树
结构最优化。
3.3 平衡二叉树的要求
(1)该二叉树必须是二叉查找树
(2)每个节点的左子树和右子树的高度差至多为1(平衡因子)。
(3)平衡因子:该节点的左子树高度-该节点右子树的高度,即左右子树的高度差
3.4 平衡树的旋转
整个实现过程是通过在一棵平衡二叉树中依次插入元素(按照二叉排序树的方式),若出现不平衡,则要根据新插
入的结点与最低不平衡结点的位置关系进行相应的调整。分为LL型、RR型、LR型和RL型4种类型,各调整方法如下
(下面用A表示最低不平衡结点):
(1)LL型
LL型调整的一般形式如上图所示,表示在A的左孩子B的左子树BL(不一定为空)中插入结点(图中阴影部分所示)而导致不平衡( h 表示子树的深度)。这种情况调整如下:①将A的左孩子B提升为新的根结点;②将原来的根结点A降为B的右孩子;③各子树按大小关系连接(BL和AR不变,BR调整为A的左子树)。
(2)RR型
RR型调整的一般形式如上图所示,表示在A的右孩子B的右子树BR(不一定为空)中插入结点而导致不平衡。这种情况调整如下:
将A的右孩子B提升为新的根结点;
将原来的根结点A降为B的左孩子
各子树按大小关系连接(AL和BR不变,BL调整为A的右子树)。
(3)LR型
LR型调整的一般形式如上图所示,表示在A的左孩子B的右子树(根结点为C,不一定为空)中插入结点而导致不平衡。这种情况调整如下:①将B的左孩子C提升为新的根结点;②将原来的根结点A降为C的右孩子;③各子树按大小关系连接(BL和AR不变,CL和CR分别调整为B的右子树和A的左子树)。
(4)RL型
RL型调整的一般形式如上图所示,表示在A的右孩子B的左子树(根结点为C,不一定为空)中插入结点而导致不平衡。这种情况调整如下:①将B的左孩子C提升为新的根结点;②将原来的根结点A降为C的左孩子;③各子树按大小关系连接(AL和BR不变,CL和CR分别调整为A的右子树和B的左子树)。
3.5 平衡二叉树实现的实例
选取一组数据分别为2,1,0,3,4,5,6,9,8,7的10个结点来构造平衡二叉树。
首先数据为2的结点作为根结点插入,接着插入1,仍是平衡的,再插入0是,2的平衡因子变为2,此时出现了不平衡,因此需要进行调整,最低不平衡结点为2,属于LL型,调整过程如图1所示。
图1
接着插入3,是平衡的,再插入4,此时出现了不平衡,结点 1 和 2 的平衡因子都为 -2,结点2为最低不平衡结点,属于RR型,调整过程如图2所示
图2
接着插入5,此时结点 1 的平衡因子为 -2,导致不平衡,结点1为最低不平衡结点,属于RR型,调整如图3所示。
图3
接着插入6,此时结点4的平衡因子为 -2,导致不平衡,结点4为最低不平衡结点,属于RR型,调整如图4所示。
图4
接着插入9,是平衡的,再插入8,此时结点 3、5、6 的平衡因子都为 -2,导致不平衡,结点6为最低不平衡结点,属于RL型,调整如图5所示。
图五
插入7,此时结点3、5的平衡因子为 -2,导致不平衡,最低不平衡结点为5,属于RL型,调整如图6所示。
图六
原文链接:https://blog.csdn.net/isunbin/article/details/81707606
4.红黑树
4.1 红黑树介绍
红黑树,一种二叉查找树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。通过对任何
一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是
接近平衡的。
它是在1972年由Rudolf Bayer发明的,当时被称为平衡二叉B树(symmetric binaryB-trees)。
后来,在1978年被 Leo J. Guibas 和 Robert Sedgewick 修改为如今的“红黑树”。
红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,
从而获得较高的查找性能。
它虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间
内做查找,插入和删除,这里的n 是树中元素的数目。
4.2 红黑树的特点
(1)节点是红色或者黑色。
(2)根节点是黑色。
(3)每个叶节点(NIL节点、空节点)是黑色的。
(4)每个红色节点的两个子节点都是黑色的(从每个叶子到根的所有路径上都不能有两个连续的红色节点)。
(5)从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
这些性质保证了根节点到任意叶子节点的路径长度,最多相差一半(因为路径上的黑色节点相等,差别只是不能相邻的红色节点个数),所以红黑树是一个基本平衡的二叉搜索树,它没有AVL树那么绝对平衡,但是同样的关键字组成的红黑树相比AVL旋转操作要少,而且删除操作也比AVL树效率更高,实际应用效果也比AVL树更出众。
4.3 红黑树的插入节点
(1)情况1:插入的是根节点。
原树是空树,此情况只会违反特点2。
对策:直接把这个节点变成黑色节点
(2)情况2:插入的节点的父节点是黑色。
不会违反性质特点2和特点4,红黑树没有被破坏。
对策:什么也不需要做。
(3)情况3:当前节点的父节点是红色且祖父节点的另一个节点(叔叔节点)是红色
此时父节点的父节点一定存在,否则插入前就已经不是红黑树。与此同时,又分为父节点是祖父节点的左子还是右子,对于对称性,我们只需要解开一个方向就可以了。在此,我们只考虑父节点为祖父节点左子的情况。
对策:将当前节点的父节点和叔叔节点涂黑,祖父节点涂红,把当前节点指向祖父节点,从新的当前节点重新开始算法
针对情况3,变化前的情况为(当前节点为4):
(4)情况4:当前节点的父节点是红色,叔叔节点是黑色,当前节点是其父节点的右子。
对策:当前节点的父节点作为新的当前节点,以新的节点为支点左旋。
如下图所示,变化前(当前节点为7):
(5)情况5:当前节点的父节点是红色,叔叔节点是黑色,当前节点是其父节点的左子
对策:父节点变为黑色,祖父节点变为红色,以父节点为支点右旋
如下图所示(当前节点为2):