难点为删除操作,参考博客更为详尽,但我整理一下思路,让兄弟节点为黑时各种情况转化的思路更为清晰。
应用场景:
二叉搜索树退化成链表,查找效率从O(logN)退化成O(N);而AVL树旋转操作复杂;红黑树是二者折中。、
一棵特殊的二叉搜索树,所有基本操作都是O(logN)。
特性:
在二叉搜索树的基础上,满足下面五个属性特性:
1.非黑即红;
2.根黑;
3.叶子(null节点)黑;
4.红节点双亲和孩子必黑;
5.任意节点到其叶子节点的黑色数相同。
核心操作:左旋、右旋、颜色调整
旋转的目的,让节点向上移动,然后修改颜色,实现红黑树平衡。
左旋:以X节点左旋,左孩子不变,右孩子变为其双亲。(另一种左旋,以X节点左旋,父母变为做孩子,左兄弟变为孩子的孩子)
右旋同理。
颜色调整,满足五点特性,尤其注意4,5点。
插入:
参考https://www.cnblogs.com/tongy0/p/5460623.html
按照二叉查找树进行调整,然后涂红。
(1)若插入点为根,涂黑;
(2)插入点的父母节点为黑,未破坏特性,直接插入;
(3)插入节点的父母节点为红,分情况讨论:
(i)叔为红,则祖父必黑,操作:父黑、叔黑、祖父红,以祖父为当前节点,判断是否破坏特性。
(ii)叔黑:
a).左左或右右:当前节点为父亲左孩子,父亲为祖父左孩子,操作:修改父黑祖红,祖父右旋;
当前节点为父亲右孩子,父亲为祖父右孩子,操作:修改父黑祖红,祖父左旋;
b).左右或右左:当前节点为父亲左孩子,父亲为祖父右孩子,操作:父亲右旋,祖父左旋,变色;
当前节点为父亲右孩子,父亲为祖父左孩子,操作:父亲左旋,祖父右旋,变色;
总结为:左左右、右右左、左右变左左、右左变右右;
原理:黑根、黑父母直接插入;
红父母、红叔叔变色递归;
红父母、黑叔叔、左孩左父母(右孩右父母),旋转变成上面情况;
红父母、黑叔叔、左孩右父母(右孩左父母),旋转变成上面情况;
删除:
参考https://www.cnblogs.com/qingergege/p/7351659.html
删除较为复杂,先按照二叉搜索树,后继节点代替删除。
(1)删除红色,直接删除;平衡;结束;
(2)删除黑色,到该节点的null节点的黑色节点数减1,需要调整颜色;
i)删除黑色节点的孩子节点是红色,红色涂黑;平衡;结束;
ii)没有红色孩子,则必为两个null节点;
a)兄弟为红:父兄换色,右兄,则双亲左旋,兄左,则双亲右旋;(目的:删除节点的兄弟变黑,变成下面d)
b)兄黑远侄红:父兄换色,父亲向删除节点旋转;平衡;结束;
c)兄黑近侄红:兄侄换色,兄弟远离删除节点旋转;变成d或e(兄黑,父红则d,父黑则e);
d)父红兄黑侄黑:父兄换色;平衡;结束;
e)父黑兄黑侄黑:兄红,所有节点到父亲的叶子null的路径的黑色都减1,则以父亲节点为被删除节点,重复(2);
参考https://www.cnblogs.com/nullllun/p/8214599.html