1. 树的分类
- 无序树:树中任意节点的子节点之间没有顺序关系,这种树称为无序树,也称为自由树;
- 有序树:树中任意节点的子节点之间有顺序关系,这种树称为有序树;
- 二叉树:每一个节点最多含有两个子树的树称为二叉树;
- 彻底二叉树:对于一颗二叉树,假设其深度为d(d>1)。除了第d层外,其它各层的节点数目均已达最大值,且第d层全部节点从左向右连续地紧密排列,这样的二叉树被称为彻底二叉树;
- 平衡二叉树(AVL树):当且仅当任何节点的两棵子树的高度差不大于1的二叉树;
- 排序二叉树(二叉查找树(英语:Binary Search Tree)):也称二叉搜索树、有序二叉树;
- 霍夫曼树:带权路径最短的二叉树称为哈夫曼树或最优二叉树;
- B树:一种对读写操做进行优化的自平衡的二叉查找树,可以保持数据有序,拥有多于两个子树。
2.AVL树
1. 参考连接
- 维基百科-AVL树
2. 旋转核心
- 在AVL树中任何节点的两个子树的高度最大差异为1
- 接受平衡因子-1,0,1,除此以外,均须要旋转
3. 旋转操做
假设平衡因子是左子树的高度减去右子树的高度所获得的值,又假设因为在二叉排序树上插入节点而失去平衡的最小子树根节点的指针为a(即a是离插入点最近,且平衡因子绝对值超过1的祖先节点),则失去平衡后进行的规律可概括为下列四种状况:segmentfault
- 单向右旋平衡处理LL:
- 因为在*a的左子树根节点的左子树上插入节点,*a的平衡因子由1增至2,导致以*a为根的子树失去平衡,则需进行一次右旋转操做;
- 单向左旋平衡处理RR:
- 因为在*a的右子树根节点的右子树上插入节点,*a的平衡因子由-1变为-2,导致以*a为根的子树失去平衡,则需进行一次左旋转操做;
- 双向旋转(先左后右)平衡处理LR:
- 因为在*a的左子树根节点的右子树上插入节点,*a的平衡因子由1增至2,导致以*a为根的子树失去平衡,则需进行两次旋转(先左旋后右旋)操做。
- 双向旋转(先右后左)平衡处理RL:
- 因为在*a的右子树根节点的左子树上插入节点,*a的平衡因子由-1变为-2,导致以*a为根的子树失去平衡,则需进行两次旋转(先右旋后左旋)操做
- 小结:
- LR(2)->左旋->LL(2)->右旋->至平衡(0)
- RR(-2)->右旋->RL(-2)->左旋->至平衡(0)
3. 红黑树
3.1 定义
首先,知足一个二叉树,其次知足5大性质,则可认为是红黑树:优化
- 节点不是红色就是黑色
- 根节点必须是黑颜色
- 全部叶子都是黑色(叶子是NIL节点)
- 每一个红色节点必须有两个黑色的子节点(也就是说任何路径上不能有连续的红色节点)
- 从任一节点到其每一个叶子的全部简单路径都包含相同数目的黑色节点
3.2 平衡核心
同AVL树旋转并保持其红黑树的特性。js动态演示-红黑树操做指针
3.3 操做核心
操做过程当中始终关注如下原则:code
- 始终保持着性质1和性质3
- 性质4只在增长红色节点、重绘黑色节点为红色,或作旋转时受到威胁。
- 性质5只在增长黑色节点、重绘红色节点为黑色,或作旋转时受到威胁。
3.4 具体操做
3.4.1 符号解释
- N:将要插入的节点(视为红色)
- P:N的父节点
- G:N的祖父节点
- U:N的叔父节点
- LR:父节点P是祖父节点G的左子节点且新节点N是其父节点P的右子节点
- LL:父节点P是祖父节点G的左子节点且新节点N是其父节点P的左子节点
- RL:父节点P是祖父节点G的右子节点且新节点N是其父节点P的左子节点
- RR:父节点P是祖父节点G的右子节点且新节点N是其父节点P的右子节点
3.4.2 插入时分状况具体操做:
- 新节点N位于树的根上,没有父节点,则可直接将其重绘为黑色;
- 新节点的父节点P是黑色,则直接插入,不做修改;(此处必然平衡,经过性质可证实,待写)
- 若是父节点P和叔父节点U两者都是红色,则将父节点P和叔父节点U修改成黑,其祖父节点修改成红,并将祖父节点视为当前节点,依状况再处理;
- 父节点P是红色而叔父节点U是黑色或缺乏,此时,必然不平衡,须要旋转,旋转参照AVL树规则,不一样之处在于重绘颜色;
- LR:先左旋一次,转换PN角色(即将旋转下来的父节点p视为当前节点N处理),此时为LL状况;
- LL:先重绘,将父节点P重绘为黑色,祖父节点G为红色,再右旋一次,此时将祖父节点视为当前节点处理;
- RL:与LR对称,操做相似,只需把旋转反向
- RR:与RR对称,操做相似,只需把旋转反向
3.4.3 删除时分状况具体操做:
3.4.3.1 删除思想
树的递归性产生了操做的递归性:若是须要删除的节点有两个儿子,那么问题能够被转化成删除另外一个只有一个儿子的节点的问题 缘由:在删除带有两个非叶子儿子的节点的时候,咱们要么找到它左子树中的最大元素、要么找到它右子树中的最小元素,并把它的值转移到要删除的节点中。咱们接着删除咱们从中复制出值的那个节点,它一定有少于两个非叶子的儿子。由于只是复制了一个值,不违反任何性质,这就把问题简化为如何删除最多有一个儿子的节点的问题。blog
3.4.3.2 删除操做
首先字母解释排序
X:最终被删除的节点(至多一个孩子节点)
P:X的父亲节点
N:X的孩子节点
S:X的兄弟节点
SL:S的左孩子
SR:S的右孩子
此时删除操做的复杂度在于 删除节点的颜色递归
- 当X为红色时,直接拿黑色节点N代替
- 当X为黑色时,若N为红色时(黑+红),拿黑色N节点代替
- 当X为黑色时,若N为黑色时(黑+黑),此时是最复杂的,共有6种状况(如下状况均已用N节点代替X节点):
- X为根节点,此时,最为简单,直接用黑色N节点替换;
- S为红色,其余节点均为黑色(相似插入时LL操做后状况),
- 均为黑色,
- 操做:将S节点重绘为红色,将P节点按状况1处理,继续1-6排查
- P为红色,其余节点均为黑色,
- S为黑色,S的左节点为红,右节点为黑,P可红可黑,但N为P的左孩子
- S为黑色,S的左节点可红可黑,右节点为红,P可红可黑,但N为P的左孩子
- 操做:P,S左旋并互换颜色,并将SR重绘为黑色,完结。
操做图:
ip
1. 相关链接
- 维基-二叉搜索树
- 维基-红黑树
- 思否-红黑树详细分析
- 思否-红黑树1
- 思否-红黑树2