LLRB 左倾红黑树(四)其他

Robert Sedgewick的左倾红黑树,

书上讲解太粗略,看不明白,好不容昂找来他的pdf,发现还是不够详细。按照作者的说法,左倾红黑树代码量少。但实际上呢,左倾红黑树的情况非常多,光2-3树,2-3-4树,2-3-4-5树的可能情况就说不完,我个人觉得作者故意忽略好多细节,因为要讲,肯定篇幅太长;而且为了简略而简略,造成有些代码太过简略而难以理解。比如delete()方法,这里为了减少代码量,把大于key和等于key的情况都放到最外面的else里面,这显然会增加代码理解难度。

    private Node delete(Node h, Key key)
    {
        if (less(key, h.key))
        {
            if (!isRed(h.left) && !isRed(h.left.left))
                h = moveRedLeft(h);
            h.left =  delete(h.left, key);
        }
        else
        {
            if (isRed(h.left))
                h = rotateRight(h);
            if (eq(key, h.key) && (h.right == null))
                return null;
            if (!isRed(h.right) && !isRed(h.right.left))
                h = moveRedRight(h);
            if (eq(key, h.key))
            {
                h.value = get(h.right, min(h.right));
                h.key = min(h.right);
                h.right = deleteMin(h.right);
            }
            else h.right = delete(h.right, key);
        }
        return fixUp(h);
    }

  

这方面,我反而觉得传统红黑树更好一些,因为传统方法就是穷举,虽然情况多,但穷举完了就完了,没有其他可能性了。而不是像这个左倾红黑树,好多情况没有说明。

我在写作这篇文章的时候,总有种,编不下去了的感觉

另外,网上有一个反对LLRB的文章,http://www.read.seas.harvard.edu/~kohler/notes/llrb.html。作者Eddie Kohler认为LLRB的主要问题,有以下几点

  1. 父指针缺失。有父指针,可以非常容易找到节点前继和后继。删除父指针,速度提升不明显;
  2. 过多的旋转。算法导论上严格界定,插入的旋转不超过2次,删除的旋转不超过3次。LLRB在自顶向下自底向上的过程中都会旋转,自顶向下即从根节点递归到目标节点的过程;自底向上即,在找到目标节点后,从目标节点返回根节点时,调用fixUp
  3. LLRB的插入、删除、查找performance都要比普通红黑树慢;(performance应该是指速度)
  4. LLRB的的实现并非像其所说的那样简化;算法导论上的左旋和右旋是对称的(symmetric,只需要一个旋转实现即可;而LLRB的左旋和右旋是不对称的(asymmetric,必须分开实现。

Robert Sedgewick的LLRB的课件,57页,deletaMax()的代码中,有一句代码错了,

h.left = deleteMax(h.left);          // 原pdf57页错误
h.right = deleteMax(h.right)         // 正确的代码

 参考文章:

http://www.cs.princeton.edu/~rs/talks/LLRB/Java/

https://blog.csdn.net/qy844083265/article/details/80716065

posted @ 2019-03-08 16:24  leondryu  阅读(309)  评论(0)    收藏  举报