杂耍者红黑树以及Java实现

2018-03-06  本文已影响0人  南宋临安府

“天下皆知美之为美,斯恶已,皆知善之为善,斯不善已。
故有无相生,难易相成,长短相形,高下相倾,音声相和,前后相随。
是以圣人处无为之事,行不言之教,万物作焉而不辞,生而不有,为而不恃,功成而弗居。
夫惟弗居,是以不去。” [1]

本篇目录:

何谓红黑树?

红黑树(red-black tree R-B Tree),是一种特殊的(自平衡)二叉树查找树,查找的时间复杂度最坏情况O(logn)。
它满足二叉查找树的特征:任意一个节点包含的键值,大于等于左孩子的键值,小于等于右孩子的键值。


RBTree.png

同时又具有如下特有属性:

  1. 每个节点或者是黑色,或者是红色。
  2. 根节点是黑色。
  3. 每个叶子节点是黑色。 [注意:这里叶子节点,是指为空的叶子节点!]
  4. 如果一个节点是红色的,则它的子节点必须是黑色的。
  5. 从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。

注意:

操作分析
基本定义
public class RBTree<T extends Comparable<T>> {

    private RBTNode<T> mRoot;// 根结点

    private static final boolean RED   = false;
    private static final boolean BLACK = true;

    public class RBTNode<T extends Comparable<T>> {
        boolean color; // 颜色
        T key;  // 关键字(键值)
        RBTNode<T> left; // 左孩子
        RBTNode<T> right; // 右孩子
        RBTNode<T> parent; // 父结点

        public RBTNode(T key, boolean color, RBTNode<T> parent, RBTNode<T> left, RBTNode<T> right) {
            this.key = key;
            this.color = color;
            this.parent = parent;
            this.left = left;
            this.right = right;
        }

    }

    ...
}

红黑树的基本操作是添加、删除和旋转。
在对红黑树进行添加或删除后,会用到旋转方法:添加或删除红黑树中的节点之后,红黑树就发生了变化,可能不满足红黑树的5条性质,也就不再是一颗红黑树了,而是一颗普通的树。而通过旋转,可以使这颗树重新成为红黑树。
简单点说,旋转的目的是让树保持红黑树的特性。
旋转包括两种:左旋 和 右旋。下面分别对红黑树的基本操作进行介绍。

左旋

对x进行左旋,意味着"将x变成一个左节点"。

/**
     * 对红黑树的节点(x)进行左旋转
     *
     * 左旋示意图(对节点x进行左旋):
     *      px                              px
     *     /                               /
     *    x                               y
     *   /  \      --(左旋)-.             / \                #
     *  lx   y                          x  ry
     *     /  \                       /    \
     *    ly  ry                     lx    ly
     *
     *
     */
右旋

对y进行左旋,意味着"将y变成一个右节点"。

/**
     * 对红黑树的节点(y)进行右旋转
     *
     * 右旋示意图(对节点y进行左旋):
     *            py                               py
     *           /                                /
     *          y                                x
     *         /  \      --(右旋)-.             /  \                     #
     *        x   ry                           lx   y
     *       / \                                   / \                   #
     *      lx  rx                                rx  ry
     *
     */
添加

将一个节点插入到红黑树中,需要执行哪些步骤呢?首先,将红黑树当作一颗二叉查找树,将节点插入;然后,将节点着色为红色;最后,通过"旋转和重新着色"等一系列操作来修正该树,使之重新成为一颗红黑树。详细描述如下:

删除

将红黑树内的某一个节点删除。需要执行的操作依次是:首先,将红黑树当作一颗二叉查找树,将该节点从二叉查找树中删除;然后,通过"旋转和重新着色"等一系列来修正该树,使之重新成为一棵红黑树。详细描述如下:

应用场景

在Jdk1.8中,HashMap最大的优化就是用红黑树替代原来的链表来解决hash键值冲突。

Java实现

RBTree.java


  1. 老子《道德经》第二章,老子故里,中国鹿邑。

上一篇 下一篇

猜你喜欢

热点阅读