解析自平衡二叉树:红黑树
红黑树的概念
**何为红黑树?**红黑树是一种自平衡二叉树(AVL),就如它名字一样,构成树的节点,不是红色就是黑色
**它是怎么样的呢?**红黑树是在普通二叉树上,对每个节点添加一个颜色作为节点的属性,这是红黑树的一个性质
**红黑树作用在哪?**典型的用途就是用于关联数组,c++中的数据结构map和set就是基于红黑树实现的,一个键对应一个值,通过键便可查找的对应的值,就是用于存储有序的数据,其时间复杂度是O(lgn),其效率很高
红黑树的性质
性质1:
节点不是红色就是黑色,这是红黑树的特征,要不叫红黑树
性质2:
根节点必须为黑色,不能为红色
性质3:
每个叶子节点(指的是NIL或者空节点的叶子节点)是黑色的
性质4:
如果一个节点是红色的,那该节点的子节点必须是黑色的
性质5:
从根节点到叶子节点的所以路径上的黑色节点的数量必须相同
红黑树的基本操作
一、添加
添加,即向红黑树中插入一个新的节点。插入之前的红黑树当然是一颗平衡的二叉树,就是有序的,那么插入之后,新的红黑树那也要是成为平衡的二叉树。
添加的第一步:将新节点的颜色设置为红色
为什么要把新节点设置为红色呢?而不是黑色?这是因为红黑树的性质之一:从根节点到其树中的叶子节点的所以路径上的黑色节点的数量必须相同,如果是黑色的话,插入树之后,就会违背这一性质,所以新插入的节点必须是红色的
添加第二步:通过左旋或者右旋操作以及着色操作使当前的二叉树变成平衡二叉树
新的节点插入后,首先看是否为平衡的,不是平衡的,通过左旋或者右旋,变成平衡二叉树;
左旋:就是将右节点作为当前的根节点,根节点作为原来右节点也就是当前根节点的左节点,原来右节点上的左节点作为现在左节点的右节点,如图:
右旋:和左旋就是反着来的,就是将左节点作为当前的根节点,根节点作为原来左节点也就是当前根节点的右节点,原来左节点上的右节点作为现在右节点的左节点,如图:
如果树中的任意节点的左右子树的高度差大于1,说明该树不是平衡二叉树了,就需要左旋和右旋进行调整,使得变成平衡二叉树。
下一步就是着色:这得分几种情况考虑:
- 当插入节点的父节点是黑色时,没有违背5个性质,这就不用进行着色处理了;
- 如果根节点为空,直接将插入的节点颜色设置为黑色即可,因为插入的就是根节点;
- 如果插入节点的父节点是红色,
这又要分成两种情况,
1 当要插入的节点的父节点的兄弟节点是红色,如:
这时,就要将父节点变为黑色,然后进行右旋操作,再左旋操作,得到一颗新的红黑树,如下图:
插入的节点在右边,步骤是一样的,不过旋转的方向应该改为先左旋,然后再右旋。
2 当要插入的节点的父节点的兄弟节点是黑色的,如:
先将父节点的颜色变为黑色,将父节点的父节点变为红色,然后进行右旋处理即可。
如果插入的节点是在右边,右旋变为左旋即可。