红黑树新解(插入)

Posted liufu627

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了红黑树新解(插入)相关的知识,希望对你有一定的参考价值。

1.  简介

红黑树是一种自平衡二叉查找树,在查找,插入和删除几个方面,性能都可以做到O(lgN)。

那怎么实现呢,首先要先看看红黑树的5个特性,只有满足这5个特性,才是红黑树。

技术图片

 

 

 

 

 

 

 

 

 

每个结点都有父结点(parent),左子结点(left)和右子结点(right), root的父结点是leaf结点。

下图便是一个简单的红黑树,

60为根结点,60的左子结点为30,60的右子结点为80,60的父结点为leaf结点; 

30的父结点为60,30的左子结点和右子结点为leaf结点;

80的父结点为60,80的左子结点和右子结点为leaf结点;

 

为了简洁,后续图片将不显示leaf结点和left,right和parent关系描述。

 技术图片技术图片

 

 

2.旋转

  在插入和删除元素的时候,都会用到旋转,所以有必要先介绍一下。

2.1 左转

比如选定一结点60,进行左转,实际是将xl转成x.right的left,有点绕,看图和代码就清楚了。

RBNode y = x.right;
x.right = y.left;
if(y.left != leaf)                  y.left.parent = x;

y.parent = x.parent;

if(x.parent == leaf)                root = y;
else if(x.parent.left == x)         x.parent.left = y;
else if(x.parent.right == x)        x.parent.right = y;

y.left = x;
x.parent = y;

 

 

技术图片

 

这只是一个示例,左转必须要按照一定规律来转,随便转肯定会出事,在插入时将会告诉你什么时候才能转。

 

2.2 右转

比如选定一点结点60,进行右转:

RBNode y = x.left;
x.left = y.right;
if(y.right != leaf)  y.right.parent = x;
y.parent
= x.parent;
if(x.parent == leaf) root = y; else if(x.parent.left == x) x.parent.left = y; else x.parent.right = y;
y.right
= x; x.parent = y;

 

技术图片

 

 

 

3.插入

现在,我们正式进入主题,元素插入后,如何进行调整,变成一颗合格的红黑树呢。以下我们将会用一些示例来讲解。

3.1 元素插入

在二叉树中插入{key:value.hashCode,value},该逻辑简单,略过,如不明白可看后面的源代码。

约定:

1.新插入的结点都为红色。

2. 某结点的左子结点指向leaf,可以说成左子结点不存在,或者没有左子结点

3. 某结点的左子结点指向leaf,可以说成左子结点存在,或者有左子结点

4.某结点的右子结点指向leaf,可以说成右子结点不存在,或者没有右子结点

4.某结点的右子结点指向leaf,可以说成右子结点存在,或者有右子结点

 

特殊场景的先决条件是:当前结点与父结点都为红色

  插入有几个特殊场景需要特别处理:

3.1.1  Case1 祖父孙 单减

转变后父结点黑色,子结点红色

技术图片

 

 

 3.1.2 Case2 祖父孙结点单增

转变后父结点黑色,子结点红色

技术图片

 

 

 3.1.3 Case3 叔结点为红色

技术图片

 

 

 3.1.4 Case4 当前结点为右子结点,父结点为左结点,叔结点没有或者黑色

技术图片

 

 

 

 3.1.5 Case5 当前结点为右子结点,父结点为左结点,叔结点没有或者黑色

技术图片

 

以上是关于红黑树新解(插入)的主要内容,如果未能解决你的问题,请参考以下文章

数据结构之红黑树

数据结构之红黑树

红黑树插入与删除完整代码(dart语言实现)

C++之红黑树

红黑树介绍和结点的插入

红黑树旋转