二叉树分完美(Perfect)完全(Complete)完满(Full),本篇涉及到二叉树的完美平衡。
Brief
理想情况下,我们希望能够保持二分查找树的平衡,但是在动态插入的过程中保证完美平衡代价太高。
为了保证查找树的平衡,现放宽灵活性,允许树中的一个节点保存多个键,由此产生出2-3查找树。但用直白的方法实现大多数操作并不方便,需要的代码和额外开销都是大量的。
本篇涉及的红黑树就是一种用来表达和实现2-3树的数据结构。
红黑树即是二叉查找树,又是2-3树,在满足基本的条件下,给出一种简洁的定义:
- 红链接均为左链接;
- 没有任何一个节点同时和两条红链接相连;
- 该树完美黑色平衡;
关于红黑树最核心特点的一个不严格表述:“将红链接画平,一棵红黑树就是一棵2-3树。”
初始化
结合代码步步分析。初始化代码如下:
|
|
每一个节点只有一个父节点指向的链接或者没有父节点(这个节点是根节点),这里约定空链接为黑色。
节点变换
节点变换使得红黑树在完成插入、删除等操作之后,仍能符合红黑树的一般定义。
左旋
左旋是为了符合定义中的“红链接均为左链接”,考虑一种情况:
此时需要通过左旋变换,将红链接“置左”,变成如下图:
此时这棵子树的父节点从h变成x并返回,代码如下:
|
|
右旋
右旋是为了符合定义中的“没有任何一个节点同时和两条红链接相连”,考虑一种情况:
此时势必需要进行右旋,然后才能经过其它操作转换这种情形,具体代码比照左旋:
|
|
色转
在右旋后往往会出现下图中出现的情况:
此时将连接在同一个节点上的两个红链接变色,然后将该指向该节点的链接设置为RED。代码如下:
|
|
实现
这里给出完整插入方法:
|
|
小结
红黑树的原理并不难理解,但是其中的变换比较冗杂,从操作上来说,运行的时间都是对数级别,最坏的情况是最左边的路径交替出现红链接和黑链接,而且红黑树继承了二叉查找树的特质,通过中序遍历,就可以按照键的比较规则有序输出。如果要进行删除操作,会涉及四种删除情形。