阅读如下须要了解普通二叉树的插入以及删除操做。算法
红黑树是在普通二叉树上,对没个节点添加一个颜色属性造成的,同时整个红黑二叉树须要同时知足一下五条性质数据结构
红黑树须要知足的五条性质:性能
在树里面的节点不是红色的就是黑色的,没有其余颜色,要不怎么叫红黑树呢,是吧。spa
根节点老是黑色的。它不能为红。3d
这个可能有点理解困难,能够看图:blog
这个图片就是一个红黑树,NIL节点是个空节点,而且是黑色的。图片
就是连续的两个节点不能是连续的红色,连续的两个节点的意思就是父节点与子节点不能是连续的红色。rem
从上图能够看见相同数量的黑色节点有三个;it
当咱们进行插入或者删除操做时所做的一切操做都是为了调整树使之符合这五条性质。class
下面咱们先介绍两个基本操做,旋转。
旋转的目的是将节点多的一支出让节点给另外一个节点少的一支,旋转操做在插入和删除操做中常常会用到,因此要熟记。
下面是左旋和右旋:
左旋:
右旋:
下面讲讲插入
咱们先明确一下各节点的叫法
由于要知足红黑树的这五条性质,若是咱们插入的是黑色节点,那就违反了性质五,须要进行大规模调整,若是咱们插入的是红色节点,那就只有在要插入节点的父节点也是红色的时候违反性质四或者是当插入的节点是根节点时,违反性质二,因此,咱们把要插入的节点的颜色变成红色。
下面是可能遇到的插入的几种情况:
一、当插入的节点是根节点时,直接涂黑便可;
二、当要插入的节点的父节点是黑色的时候。
这个时候插入一个红色的节点并无对这五个性质产生破坏。因此直接插入不用在进行调整操做。
三、若是要插入的节点的父节点是红色且父节点是祖父节点的左支的时候。
这个要分两种状况,一种是叔叔节点为黑的状况,一种是叔叔节点为红的状况。
当叔叔为黑时,也分为两种状况,一种是要插入的节点是父节点的左支,另外一种是要插入的节点是父亲的右支。
咱们先看一下当要插入的节点是父节点的左支的状况:
这个时候违反了性质四,咱们就须要进行调整操做,使之符合性质四,咱们能够经过对祖父节点进行右旋同时将祖父节点和父节点的颜色进行互换,这样就变成了:
通过这样的调整能够符合性质四而且不对其余性质产生破坏。
当插入的节点是父节点的右支的时候:
当要插入的节点是父节点的右支的时候,咱们能够先对父节点进行左旋,变成以下:
若是咱们把原先的父节点看作是新的要插入的节点,把原先要插入的节点看作是新的父节点,那就变成了当要插入的节点在父节点的左支的状况,对,是的,就是按照当要插入的节点在父节点的左支的状况进行旋转,旋转完以后变成以下:
四、若是要插入的节点的父节点是红色且父节点是祖父节点的右支的时候;
这个时候的状况跟状况3所表述的状况是一个镜像,将状况3的左和右互换一下就能够了。
五、若是要插入的节点的父节点是红色而且叔叔节点也为红色,以下:
这个时候,只需将父亲节点和叔叔节点涂黑,将祖父节点涂红。
以上就是插入的所有过程。
首先你要了解普通二叉树的删除操做:
一、若是删除的是叶节点,能够直接删除;
二、若是被删除的元素有一个子节点,能够将子节点直接移到被删除元素的位置;
三、若是有两个子节点,这时候就能够把被删除元素的右支的最小节点(被删除元素右支的最左边的节点)和被删除元素互换,咱们把被删除元素右支的最左边的节点称之为后继节点(后继元素),而后在根据状况1或者状况2进行操做。如图:
将被删除元素与其右支的最小元素互换,变成以下图所示:
而后再将被删除元素删除:
咱们下面所称的被删除元素,皆是指已经互换以后的被删除元素。
加入颜色以后,被删除元素和后继元素互换只是值得互换,并不互换颜色,这个要注意。
一、当被删除元素为红时,对五条性质没有什么影响,直接删除。
二、当被删除元素为黑且为根节点时,直接删除。
三、当被删除元素为黑,且有一个右子节点为红时,将右子节点涂黑放到被删除元素的位置,如图:
由
变成
四、当被删除元素为黑,且兄弟节点为黑,兄弟节点两个孩子也为黑,父节点为红,此时,交换兄弟节点与父节点的颜色;NIL元素是指每一个叶节点都有两个空的,颜色为黑的NIL元素,须要他的时候就能够把它当作两个黑元素,不须要的时候能够忽视他。
如图:
由
变成:
五、当被删除元素为黑、而且为父节点的左支,且兄弟颜色为黑,兄弟的右支为红色,这个时候须要交换兄弟与父亲的颜色,并把父亲涂黑、兄弟的右支涂黑,并以父节点为中心左转。如图:
由:
变成:
六、当被删除元素为黑、而且为父节点的左支,且兄弟颜色为黑,兄弟的左支为红色,这个时候须要先把兄弟与兄弟的左子节点颜色互换,进行右转,而后就变成了规则5同样了,在按照规则5进行旋转。如图:
由
先兄弟与兄弟的左子节点颜色互换,进行右转,变成:
而后在按照规则5进行旋转,变成:
七、当被删除元素为黑且为父元素的右支时,跟状况5.状况6 互为镜像。
八、被删除元素为黑且兄弟节点为黑,兄弟节点的孩子为黑,父亲为黑,这个时候须要将兄弟节点变为红,再把父亲看作那个被删除的元素(只是看作,实际上不删除),看看父亲符和哪一条删除规则,进行处理变化如图:
由:
变成:
九、当被删除的元素为黑,且为父元素的左支,兄弟节点为红色的时候,须要交换兄弟节点与父亲结点的颜色,以父亲结点进行左旋,就变成了状况4,在按照状况四进行操做便可,变化以下:
由:
交换兄弟节点与父亲结点的颜色,以父亲结点进行左旋 变成:
在按照状况四进行操做,变成:
好了,删除的步骤也讲完,没有讲到的一点就是,在添加删除的时候,时刻要记得更改根元素的颜色为黑。
这里并无语言实现,只是讲了一下红黑树的插入删除步骤,你能够根据步骤本身把红黑树实现。
点击这里,照着规则一步一步的构建一个红黑树吧。
一、红黑树的实现实际上是一个二、三、4树,只是将双节点或者三节点用红色进行了标示,若是你将红色节点放到和它父元素相同的高度,并把它和父元素看作是一个元素,你就会发现,变成了一个高度为lgN的二叉树,这个2.3.4树对红黑树颇有启发意义。
二、上面的步骤其实能够不用死记硬背,是能够推导出来的,由于咱们是把一个平衡但经过插入或者删除破坏了平衡的红黑树再次平衡,同过旋转让位,改变红黑颜色,使之符合那五条基本性质。好比遇到删除操做状况四的时候,咱们能够把那个删除元素去除,发现左边比右边少一个黑元素,这个时候,怎么办,咱们发现兄弟节点的子元素有一个红元素,操做这个不会影响那五条性质,因此咱们经过变换颜色,旋转,便可让左右两边的的黑色数目同样。
三、旋转操做的目的是出让一个元素到另外的地方而且符合二叉树左小右大的性质,交换颜色的目的是为了保持红黑树的那五条性质。
四、要时刻记得 ,一切的操做都是为了保持那五条性质。
最后的最后,其实还有一种更为简单的红黑二叉树,这个简单的红黑二叉树其实是一个2.3树,他只容许左节点为红节点,可是性能上确定是不如这个红黑树。这个简单的红黑二叉树在《算法》第四版有介绍,掌握完以后再看这个简单的红黑二叉树,就会觉着简单 easy。
最后的最后的最后,必定要尝试着本身推导一下插入删除规则啊,否则常常忘,是睡一觉起来再看就有点懵逼的那种忘。