红黑树讲解

二叉查找树(BST)

  1. 左子树上所有结点的值均小于或等于它的根结点的值。
  2. 右子树上所有结点的值均大于或等于它的根结点的值。
  3. 左右子树每个也必须是二叉查找树
    下图中这棵树,就是一颗典型的二叉查找树:
    红黑树讲解_第1张图片

推荐一个很好用的网站,Data Structure Visualizations它包括队列、栈、堆、图、树等等,并且支持递归、排序、检索等众多算法的动态演示。想看二叉查找树动态演示的小伙伴,请点击链接:Data Structure Visualizations-数据结构

  1. 查找:从根节点出发,一层一层比较大小直到找到要查找的值。查找所需的最大次数为二叉查找树的高度。(举例:查找10,从9出发,发现10>9,看右孩子12,发现10<12,看左孩子,找到10)
  2. 它存在一个很严重的缺陷,二叉查找树可能退化成链表(举例:依次插入1-5。结果见下图)。
    红黑树讲解_第2张图片

我们可以发现此时的二叉查找树退化成了链表,为了解决这一现象红黑树诞生了。

红黑树

性质

  1. 节点是红色或黑色
  2. 根节点是黑色。
  3. 每个叶子节点都是黑色的空节点(NIL节点)
  4. 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
  5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

这些性质保证了红黑树的自平衡:从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。

添加的节点必须为红色
5性质决定的:从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

  1. 假如任意插入的节点是黑色节点,则连续插入两个黑色节点后,就不满足第四点性质(肯定有一边的黑色节点多于另外一边);
  2. 但是连续插入两个红色节点就不会破坏性质四,因为连续两个红色节点可以根据红黑树的变换规则进行变色或者旋转的调整,以达到标准的红黑树!

那么它是怎么解决二叉查找树退化成链表的呢?(举例:依次插入1-5。结果见下图,注意001,003,005不是叶子节点。叶子节点都是黑色的空节点(NIL节点)全文没有标出)。演示链接
红黑树讲解_第3张图片
演示时,我们可以发现当我们插入数据时,如果违背了上面的性质。就会做出相应的调整。调整方式有变色,左旋转,右旋转

变色的情况:当前结点的父亲是红色,且它的叔结点也是红色
举例:添加1-3后再添加4时
红黑树讲解_第4张图片

Node and parent are both red. Uncle of node is red – push blackness down from grandparent这是演示时的的英文介绍,大概意思是:该节点和它的父节点都为红,它的叔结点也是红色:从祖父节点开始全部变色(红变黑,黑变红)除了插入的节点

调整:从祖父节点开始全部变色(红变黑,黑变红)除了插入的节点
调整后
红黑树讲解_第5张图片
上面是一步到位。它可以分为几个小步骤:

  1. 发现003和004都为红,不符合规则4,调整:003从红色变成黑色
  2. 003变成黑色,不符合规则5,调整:把002从黑色变成红色
  3. 发现001和002都为红,不符合规则4,调整:001从红色变成黑色

左旋转的情况:当前父节点是红色,叔节点是黑色,且当前的节点是右子树
举例:添加1-4后再添加5时

红黑树讲解_第6张图片

Node and parent are both red. Node is right child, parent is right childCan fix extra redness with a single rotation意思是:该节点和父节点都是红色的。节点是右子节点,父节点是右子节点可以通过一次旋转来修复额外的红色

左旋转:想象这是一根绳子,手提起 004节点,然后将004的左孩子变成003的右孩子,即可。
红黑树讲解_第7张图片
变色:把父节点004变成黑色 ,把祖父节003点变为红色。红黑树讲解_第8张图片

右旋的情况:当前父节点是红色,叔节点是黑色,且当前的节点是左子树。
举例:添加5-2后再添加1时
红黑树讲解_第9张图片

Node and parent are both red. Node is left child, parent is left childCan fix extra redness with a single rotation 节点和父节点都是红色的。节点是左子节点,父节点是左子节点可以通过一次旋转来修复额外的红色

右旋转:想象这是一根绳子,手提起 002节点,然后将 002的右孩子变成003的左孩子,即可
红黑树讲解_第10张图片
变色: 把父节点002变成黑色 ,把祖父节003点变为红色。
红黑树讲解_第11张图片
左右的情况:父节点是祖父节点的左子树且是红色,叔节点是黑色,且当前的节点是右子树。
红黑树讲解_第12张图片
先左旋:想象这是一根绳子,手提起 004节点,即可。
红黑树讲解_第13张图片
再右旋:想象这是一根绳子,手提起 004节点,然后将 004的右孩子变成005的左孩子,即可
红黑树讲解_第14张图片
最后变色;把父节点004变成黑色 ,把祖父节005点变为红色。(注意右旋的当前节点为003)
红黑树讲解_第15张图片
右左的情况:父节点是祖父节点的右子树且是红色,叔节点是黑色,且当前的节点是左子树。
红黑树讲解_第16张图片

先右旋:想象这是一根绳子,手提起 0015节点,即可。
红黑树讲解_第17张图片

再左旋:想象这是一根绳子,手提起 0015节点,然后将 0015的左孩子变成0013的右孩子,即可
红黑树讲解_第18张图片

最后变色;把父节点0015变成黑色 ,把祖父节0013点变为红色。(注意左旋的当前节点为0018)
红黑树讲解_第19张图片
红黑树的本质:红黑树是对2-3查找树的改进,它能用一种统一的方式完成所有变换。
想了解2-3查找树转换为红黑树的过程的小伙伴,请点击下方大佬链接。真的写的很详细史上最简单清晰的红黑树讲解

你可能感兴趣的:(笔记,算法,数据结构)