红黑树

2018-03-14  本文已影响0人  edolovee

定义

红黑树是一个平衡的二叉树,其满足如下性质:

  1. 节点是红色或者是黑色
  2. 根节点是黑色
  3. 每个叶节点是黑色
  4. 每个红色节点的两个子节点都是黑色的
  5. 从根节点到任何叶子节点经过的黑色几点数相同

保持平衡的操作

  1. 左旋
    比如对A左旋,则操作如下:
image.png
  1. 右旋
    比如对A右旋,则操作如下:

保持平衡情况分析

  1. 插入

代码实现参考TreeMap的实现

private void fixAfterInsertion(Entry<K,V> x) {
    x.color = RED;
    while (x != null && x != root && x.parent.color == RED) {
        if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {
            Entry<K,V> y = rightOf(parentOf(parentOf(x)));
            if (colorOf(y) == RED) {//如果y为null,则视为BLACK
                setColor(parentOf(x), BLACK);              // 情况1
                setColor(y, BLACK);                        // 情况1
                setColor(parentOf(parentOf(x)), RED);      // 情况1
                x = parentOf(parentOf(x));                 // 情况1
            } else {
                if (x == rightOf(parentOf(x))) {
                    x = parentOf(x);                       // 情况2
                    rotateLeft(x);                         // 情况2
                }
                setColor(parentOf(x), BLACK);              // 情况3
                setColor(parentOf(parentOf(x)), RED);      // 情况3
                rotateRight(parentOf(parentOf(x)));        // 情况3
            }
        } else {
            Entry<K,V> y = leftOf(parentOf(parentOf(x)));
            if (colorOf(y) == RED) {
                setColor(parentOf(x), BLACK);              // 情况4
                setColor(y, BLACK);                        // 情况4
                setColor(parentOf(parentOf(x)), RED);      // 情况4
                x = parentOf(parentOf(x));                 // 情况4
            } else {
                if (x == leftOf(parentOf(x))) {
                    x = parentOf(x);                       // 情况5
                    rotateRight(x);                        // 情况5
                }
                setColor(parentOf(x), BLACK);              // 情况6
                setColor(parentOf(parentOf(x)), RED);      // 情况6
                rotateLeft(parentOf(parentOf(x)));         // 情况6
            }
        }
    }
    root.color = BLACK;
}

应用以及 性能

linux的虚拟内存管理以及java中的treeset和treemap,其时间复杂度在O(lgn),此外,任何不平衡都会在3次旋转之内解决。这一点是AVL所不具备的。

上一篇 下一篇

猜你喜欢

热点阅读