红黑树,由于在二叉查找树上进行的insert,delete,search等的时间都为o(h),故保持良好的h可以避免最坏运行时间,红黑树就是这样一种保持良好高度的二叉查找树。
首先看看红黑树必须满足的几个性质:
1):每个节点非红即黑
2):根节点是黑色的
3):每个叶节点(NIL)均是黑色的
4):一个节点为红,则它的两个儿子均是黑色的。(必有两个儿子的原因在于需要保持黑高度相同)换句话说,一个节点是红色的那么它的父节点必是黑色的。
5):从某内部节点x到叶子节点的任一路径的黑高度相同。(黑高度即黑色节点的个数,不包括x节点但包括叶子节点NIL)
由于以上性质,使得从根到任一叶子节点的黑色节点个数至少有一半以上(证明:设从根到某一叶子节点所有节点为total个,红色节点为x个,黑色节点为y个,故x+y=total;由于一个节点为红色的话那么它的两个儿子必须是黑色的,即出现一个红色节点那么它的子节点必须出现黑节点,故y>=x;所以total = x+y<=y+y -> y>=total/2;因此一条路径上黑色节点数必大于等于总节点数),故红黑树的高度h=o(log n)
旋转,若要旋转某个节点x。
左旋转,x的右子节点为y,那么就以x链接y的边为轴不变,将y变成x的父节点。
右选择,x的左子节点为y,那么就以x链接y的边为轴不变,将y变成x的父节点。
红黑树的插入。若要插入一个节点z,那么插入时必须着色为红色,否则会影响黑高度。当插入后,可能导致红黑树的5个性质不能保持。由于插入的节点z是在叶子节点上,故破坏的只能是性质2)和性质4)。
对于性质2),当红黑树为空时才可能破坏它,因此插入后仅有一个节点,只需将颜色变成黑色即可。
对于性质4):当插入的节点z的父节点也为红色时,那么需要调整;设z的父节点为p(z),爷爷为p(p(z)),因为父亲是红色的那么爷爷必然是黑色的。这时要对于z的叔叔节点y的颜色进行讨论(z的叔叔即是爷爷的另一个子节点)。
当y为红色时,那么由于z是红色,父亲和叔叔都是红色,而爷爷是黑色,那么只需将爷爷变成红色,父亲和叔叔都变成黑色即将爷爷以下的节点都保持了性质4),而爷爷此时为红色,可能由破坏了上面的节点,即z此时向上移动两层到爷爷节点,此时再对z进行调整。
当y为黑色时,此时z和父亲为红色,叔叔也爷爷均为黑色,那么此时要进行一次或者两次旋转,将z调整到爷爷的位置。