普通红黑树过于复杂,这里采用一种比较简单的左倾红黑树,定义略有不同,实现效果更好。
规定
- 所有红链接均为左链接
- 没有任何一个结点连着两个红链接
- 该树是完美黑色平衡的
操作
- 插入结点的链接颜色均为红色
- 如果右结点链接为红色,左旋转
- 如果左节点和左左节点链接均为红色,右旋转
- 如果同层左右结点链接均为红色,它们同时变黑,父节点变红色
- 根结点永远设置为黑色,如果由红变黑一次,说明树的高度增加
插入-伪代码实现
public void put(K key, V value){
root = put (root, key, value);
root.color = BLACK; //根结点永远设置为黑色
}
public void put(Node root, K key, V value){
if(root == null)
return new Node(key,value,RED);//RED表示,插入结点的链接颜色均为红色
if(key < root.key) root.left = put(root.left, key, value);
else if(key > root.key) root.right = put(root.right, key, value);
else root.value = value;
if(右结点链接为红色) {左旋转}
if(左节点和左左节点链接均为红色) {右旋转}
if(同层左右结点链接均为红色) {同时变黑,父节点变红色}
return root;
}
复杂度
插入的复杂度在logN到2logN之间,简单的说是log复杂度的查询。
删除
删除是一种非常麻烦的过程,首先要看是不是根结点,如果根结点而且是红色的比较简单,直接删除。如果是根结点但是是黑色则需要右旋转,并且进行颜色转换。如果不是根结点,则找到与他最近的一个根结点做交换继承另一方的颜色,然后同上。
这里不给出删除的实现方法,但是可以知道的是删除的时间复杂度也不高。