<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    E81086713E446D36F62B2AA2A3502B5EB155

    Java雜家

    雜七雜八。。。一家之言

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      40 Posts :: 1 Stories :: 174 Comments :: 0 Trackbacks
    紅黑樹可能是要考慮情況最多的BST樹了,它有自己的規則(見代碼的注釋),通過這些規則可以保證花費較小的代價來達到相對平衡。
    注意,紅黑樹仍然不是平衡樹,但是統計性能要好于AVL樹。
    要保持紅黑樹的規則,主要通過兩類操作,一類是換色,一類還是旋轉。
    紅黑樹插入主要要解決紅-紅沖突,而刪除主要則解決“雙黑”

    同樣,紅黑樹的刪除節點實現是最復雜的,不過,復雜也就在于考慮的情況多,掌握了這幾種情況實現還是不困難。
    其實,紅黑樹其實是一顆擴充的二叉樹,所以也是滿二叉樹,其空節點可以看做是擴充的葉節點。但是紅黑樹的擴充葉節點是有特殊意義的。


    下面是代碼:

    package algorithms.tree;

    /**
     * R-B Tree has following four rules:
     * 1)every node is either red or black
     * 2)root and empty node (external leaf node) are always black.
     * 3)the red node's parent node must be black
     * 4)every simple path start from node X to its descendant contains same number of black node
     * 
     * 
     * 
    @author yovn
     *
     
    */
    public class RBTree<extends Comparable<E>> extends DefaultBSTree<E> implements BSTree<E> {

        
        
        
    public static class RBPrinter<extends Comparable<E>> implements DefaultBSTree.NodeVisitor<E>
        {

            @Override
            
    public void visit(E ele) {
                
                
            }

            @Override
            
    public void visitNode(algorithms.tree.DefaultBSTree.BSTNode<E> node) {
                RBNode
    <E> n=(RBNode<E>)node;
                
    if(!n.isNull())
                System.out.print(n.key
    +"("+(n.color==RBNode.RED?"RED":"BLACK")+"),");
                
            }
            
        }
        
    static class RBNode<extends Comparable<E>> extends BSTNode<E>
        {



            
    static final boolean RED=false;
            
    static final boolean BLACK=true;
            
            
            
            RBNode
    <E> parent;
            
    boolean color;//red or black
            
            
            RBNode(RBNode
    <E> p,E key,boolean color) {
                
    super(key);
                
    this.color=color;
                
    this.parent=p;
                
            }
            
            
            
            
    final boolean isNull(){return key==null;}
            
        }
        
        
            
        @Override
        
    public final boolean delete(E ele) {
            RBNode
    <E> cur;
            
            
    int cmp;
            
    if(root==null)return false;
            cur
    =(RBNode<E>)root;
            
    while(!cur.isNull()&&(cmp=ele.compareTo(cur.key))!=0)
            {
                
    if(cmp<0)cur=(RBNode<E>)cur.left;
                
    else cur=(RBNode<E>)cur.right;
                    
            }
            
    if(cur.isNull())
            {
                
    //can't find specified key
                return false;
            }
            
    if(!((RBNode<E>)cur.left).isNull()&&!((RBNode<E>)cur.right).isNull())
            {
                RBNode
    <E> prev=(RBNode<E>)cur.left;
            
                
    while(!((RBNode<E>)prev.right).isNull())
                {
                    
                    prev
    =(RBNode<E>)prev.right;
                }
                cur.key
    =prev.key;
                cur
    =prev;
            
            }
            
    if(!((RBNode<E>)cur.left).isNull())
            {
                
    if (cur == root) {
                    root 
    = cur.left;
                    ((RBNode
    <E>)root).color=RBNode.BLACK;
                    
    return true;
                }
                
                
    if(cur.parent.left==cur)
                {
                    cur.parent.left
    =cur.left;
                    ((RBNode
    <E>)cur.left).parent=cur.parent;
                }
                
    else
                {
                    cur.parent.right
    =cur.left;
                    ((RBNode
    <E>)cur.left).parent=cur.parent;
                }
                
    if(cur.color==RBNode.BLACK)
                {
                    ((RBNode
    <E>)cur.left).color=RBNode.BLACK;
                }
            }
            
    else if(!((RBNode<E>)cur.right).isNull())
            {
                
    if (cur == root) {
                    root 
    = cur.right;
                    ((RBNode
    <E>)root).color=RBNode.BLACK;
                    
    return true;
                }
                
                
    if(cur.parent.left==cur)
                {
                    cur.parent.left
    =cur.right;
                    ((RBNode
    <E>)cur.right).parent=cur.parent;
                }
                
    else
                {
                    cur.parent.right
    =cur.right;
                    ((RBNode
    <E>)cur.right).parent=cur.parent;
                }
                
    if(cur.color==RBNode.BLACK)
                {
                    ((RBNode
    <E>)cur.right).color=RBNode.BLACK;
                }
            }
            
    else
            {
                
    if(cur==root)
                {
                    root
    =null;
                    
    return true;
                }
                RBNode
    <E> todo;
                
    if(cur.parent.left==cur)
                {
                    todo
    =newNullNode(cur.parent);
                    cur.parent.left
    =todo;
                }
                
                
    else
                {
                    todo
    =newNullNode(cur.parent);
                    cur.parent.right
    =todo;
                }
                
    if(cur.color==RBNode.BLACK)
                {
                    
    //now todo is a double black node, we will eliminate the double black
                    fixup_double_black(todo);
                }
                
            }
            
            
    return true;
        }

        @Override
        
    public E findMax() {
            
    if(isEmpty())return null;
            BSTNode
    <E> node=root;
            
    while(!((RBNode<E>)node.right).isNull())
            {
                node
    =node.right;
            }
            
    return node.key;
        }


        @Override
        
    public E findMin() {
            
    if(isEmpty())return null;
            BSTNode
    <E> node=root;
            
    while(!((RBNode<E>)node.left).isNull())
            {
                node
    =node.left;
            }
            
    return node.key;
        }

        
    private final RBNode<E> newNullNode(RBNode<E> p)
        {
            
    return new RBNode<E>(p,null,RBNode.BLACK);
        }
        
        
    private final RBNode<E> newNormalNode(RBNode<E> p,E key, boolean color)
        {
            RBNode
    <E> node= new RBNode<E>(p,key,color);
            node.left
    =newNullNode(node);
            node.right
    =newNullNode(node);
            
    return node;
        }

        
    private final void fixup_double_black(RBNode<E> cur) {
            
            RBNode
    <E> sibling;
            RBNode
    <E> p;
        
            
    while(cur!=root)//until its parent,parent maybe double black 
            {
                p
    =cur.parent;
                
    if(p.left==cur)
                {
                    sibling
    =(RBNode<E>)p.right;
                    
    if(sibling.color==RBNode.RED)
                    {
                        rotate_from_right(p);
                        p.color
    =RBNode.RED;
                        sibling.color
    =RBNode.BLACK;//actually, p.parent==sibling, remember we have done one rotation
                        
    //this case  transformed to another case handled in other place
                    }
                    
    else 
                    {
                        
    if(((RBNode<E>)sibling.right).color==RBNode.RED)
                        {
                            rotate_from_right(p);
                            sibling.color
    =p.color;//also, p.parent==sibling, some textbook say here sibling's color can be red while not violate the 3th rule, i don't think so.
                            p.color=RBNode.BLACK;
                            ((RBNode
    <E>)sibling.right).color=RBNode.BLACK;
                            
    //ok done!
                            return;
                            
                        }
                        
    else if(((RBNode<E>)sibling.left).color==RBNode.RED)
                        {
                            rotate_from_left(sibling);
                            sibling.color
    =RBNode.RED;
                            sibling.parent.color
    =RBNode.BLACK;//its parent was previously be its left child, remember we have done a left rotation from sibling
                            
                            
    // now transformed to previous case, double black 's sibling(black) have right child colored red
                            
                        }
                        
    else //  sibling's two children are both black
                        {
                            
    //re-coloring the sibling and parent
                            sibling.color=RBNode.RED;
                            
    if(p.color==RBNode.BLACK)
                            {
                                cur
    =p;
                                
    //now the cur node was not double black node ,but p was a double black
                            }
                            
    else
                            {
                                p.color
    =RBNode.BLACK;//eliminated the double black node 
                                return;
                            }
                        }
                    }
                }
                
    else
                {
                    sibling
    =(RBNode<E>)p.left;
                    
    if(sibling.color==RBNode.RED)
                    {
                        rotate_from_left(p);
                        p.color
    =RBNode.RED;
                        sibling.color
    =RBNode.BLACK;//actually, p.parent==sibling, remember we have done one rotation
                        
    //this case  transformed to another case handled in other place
                    }
                    
    else 
                    {
                        
    if(((RBNode<E>)sibling.left).color==RBNode.RED)
                        {
                            rotate_from_left(p);
                            sibling.color
    =p.color;//also, p.parent==sibling, some textbook say here sibling's color can be red while not violate the 3th rule, i don't think so.
                            p.color=RBNode.BLACK;
                            ((RBNode
    <E>)sibling.left).color=RBNode.BLACK;
                            
    //ok done!
                            return;
                            
                        }
                        
    else if(((RBNode<E>)sibling.right).color==RBNode.RED)
                        {
                            rotate_from_right(sibling);
                            sibling.color
    =RBNode.RED;
                            sibling.parent.color
    =RBNode.BLACK;//its parent was previously be its right child, remember we have done a left rotation from sibling
                        
                            
    // now transformed to previous case, double black 's sibling(black) have right child colored red
                            
                        }
                        
    else //  sibling's two children are both black
                        {
                            
    //re-coloring the sibling and parent
                            sibling.color=RBNode.RED;
                            
    if(p.color==RBNode.BLACK)
                            {
                                cur
    =p;
                                
    //now the cur node was not double black node ,but p was a double black
                            }
                            
    else
                            {
                                p.color
    =RBNode.BLACK;//eliminated the double black node 
                                return;
                            }
                        }
                    }
                }
            }
            
        }

        



        @Override
        
    public final void insert(E ele) {
            
    if(root==null)
            {
                root
    =newNormalNode(null,ele,RBNode.BLACK);//now root's black-height(bh) is 1
                return;
            }
            RBNode
    <E> ret=_insert((RBNode<E>)root,ele);//first insert it
            _insert_fixup(ret);//fix-up the R-B tree from node cur;
        }
        
        
        
    private final void _insert_fixup(RBNode<E> cur) {
            
            RBNode
    <E> p,g;
        
            
    //we should fix until it is black colored
            while(cur!=root&&cur.color==RBNode.RED)
            {
                p
    =cur.parent;
                
    if(p.color==RBNode.BLACK)
                {
                    
    //that's fine, the insertion will not change any black height, and will not violate any rule.
                    return;
                }
                g
    =p.parent;//we can assume the p is not null now.
                
                
    if(p==g.left)
                {
                    RBNode
    <E> uncle=(RBNode<E> )g.right;
                    
    if(uncle.color==RBNode.RED)
                    {
                        
    //re-coloring
                        g.color=RBNode.RED;
                        uncle.color
    =p.color=RBNode.BLACK;
                        
                        
    //now the g maybe conflict with its parent;
                        cur=g;
                    }
                    
    else
                    {
                        
    if(cur==p.right)
                        {
                            
    //this case we should do left rotation, and then it will transform to next case
                            cur=rotate_from_right(p);
                            cur
    =(RBNode<E>)cur.left;
                            
    //transformed to next case    
                        }
                        
                        cur
    =rotate_from_left(g);
                        cur.color
    =RBNode.BLACK;
                        ((RBNode
    <E>)cur.left).color=((RBNode<E>)cur.right).color=RBNode.RED;
                                        
                    
                    }
                    
                }
                
    else
                {
                    RBNode
    <E> uncle=(RBNode<E> )g.left;
                    
    if(uncle.color==RBNode.RED)
                    {
                        
    //re-coloring
                        g.color=RBNode.RED;
                        uncle.color
    =p.color=RBNode.BLACK;
                        
                        
    //now the g maybe conflict with its parent;
                        cur=g;
                    }
                    
    else
                    {
                        
    if(cur==p.left)
                        {
                            
    //this case we should do right rotation, and then it will transform to next case
                            cur=rotate_from_left(p);
                            cur
    =(RBNode<E>)cur.right;
                            
    //transformed to next case    
                        }
                        
                        cur
    =rotate_from_right(g);
                        cur.color
    =RBNode.BLACK;
                        ((RBNode
    <E>)cur.left).color=((RBNode<E>)cur.right).color=RBNode.RED;
                                        
                    
                    }
                }
                    
            }
            ((RBNode
    <E>)root).color=RBNode.BLACK;
            
            
        }




        
    private final RBNode<E> rotate_from_right(RBNode<E> p) {
            
            RBNode
    <E> g=p.parent;
            RBNode
    <E> cur=(RBNode<E>)p.right;
            
            p.right
    =cur.left;
            
    if(cur.left!=null)((RBNode<E>)cur.left).parent=p;
            
            cur.left
    =p;
            p.parent
    =cur;
            
            
            
    if(g!=null)
            {
                
    if(g.left==p)g.left=cur;
                
    else g.right=cur;
            }
            
    else root=cur;
            
            cur.parent
    =g;
            
    return cur;
            
        
        }




        
    private final RBNode<E> rotate_from_left(RBNode<E> p) {
            RBNode
    <E> g=p.parent;
            RBNode
    <E> cur=(RBNode<E>)p.left;
            
            p.left
    =cur.right;
            
    if(cur.right!=null)((RBNode<E>)cur.right).parent=p;
            
            cur.right
    =p;
            p.parent
    =cur;
            
            
            
    if(g!=null)
            {
                
    if(g.left==p)g.left=cur;
                
    else g.right=cur;
            }
            
    else root=cur;
            
            cur.parent
    =g;
            
    return cur;
        }




        
    private final RBNode<E> _insert(RBNode<E> cur,E ele)
        {
            
            RBNode
    <E> parent=null;
            
    int cmp;
            
    boolean left=false;
            
    while(!cur.isNull()&&(cmp=ele.compareTo(cur.key))!=0)
            {
                parent
    =cur;
                
    if(cmp<0)
                {
                    cur
    =(RBNode<E>)cur.left;
                    left
    =true;
                    
                }
                
    else {cur=(RBNode<E>)cur.right;left=false;}
                
            }
            
    if(!cur.isNull())throw new IllegalArgumentException("can't insert duplicate key!");
            cur
    =newNormalNode(parent,ele,RBNode.RED);
            
    if(left)parent.left=cur;
            
    else parent.right=cur;
            
    return cur;
        }




        
    /**
         * 
         
    */
        
    public RBTree() {
                root
    =null;
        }

    }





    posted on 2007-12-20 18:25 DoubleH 閱讀(8497) 評論(20)  編輯  收藏

    Feedback

    # re: 紅黑樹的Java實現 2007-12-23 22:43 bwl
    似乎是老外寫的。。。。。。。。  回復  更多評論
      

    # re: 紅黑樹的Java實現 2007-12-24 12:26 Javacap
    @bwl
    不好意思,我通常寫代碼都喜歡英文注釋,很少寫中文注釋,要么就干脆不注釋,老感覺寫代碼加上中文注釋挺別扭的,代碼哪怕一個字也沒有參看別人的。  回復  更多評論
      

    # re: 紅黑樹的Java實現 2007-12-24 14:47 過路
    Java功底不錯。
      回復  更多評論
      

    # re: 紅黑樹的Java實現[未登錄] 2008-02-14 18:20 wangj
    可能你使用的Java的IDE對中文支持不好,良好的代碼是要盡量給別人看的,只要有基礎的人看不懂,特別加了注釋還不如不加的話,那最好不加。
    其實很多JSP和J2ME程序都要使用中文的,因為畢竟面對的是中文界面用戶,從理論上來說數據結構是不需要中文的,但是數據結構一般都是用C或者Delphi編的,然后通過JNI調用的,因此用Java就是用對象,你可惜做的并不好  回復  更多評論
      

    # re: 紅黑樹的Java實現[未登錄] 2008-02-14 18:24 wangj
    @Javacap
    你的程序還不是老外寫的,如果向老外看齊的話,請先把軟件書寫規范點。問題太多了,直說2點吧,第一等號兩邊都要空格,第二,多條語句必須寫多行
      回復  更多評論
      

    # re: 紅黑樹的Java實現[未登錄] 2009-01-14 11:41 wangj
    @wangj
    2b真多  回復  更多評論
      

    # re: 紅黑樹的Java實現[未登錄] 2009-01-14 16:59 wangj
    wangj = 2b
      回復  更多評論
      

    # re: 紅黑樹的Java實現 2009-07-28 15:35 satitan
    如果提不出實質性的意見,請像我一樣稱贊一下博主的OPEN精神:非常好,已閱  回復  更多評論
      

    # re: 紅黑樹的Java實現 2009-08-19 22:03 lixmin
    我喜歡, 已閱  回復  更多評論
      

    # re: 紅黑樹的Java實現[未登錄] 2009-12-10 22:53 Daniel
    @wangj

    請那些不懂算法別在這里亂評論,正如有位仁兄所說“2B真多”
    樓主我很欣賞  回復  更多評論
      

    # re: 紅黑樹的Java實現 2009-12-19 22:21 tcelvis
    能不能把其他幾個相關類的代碼也給放出來?DefaultBSTree和BSTree等等,光看這個有些不明白。為什么RBnode中只定義parents而直接使用父類的left和right?據我所知BSTree的結點也應該有parents域才對。  回復  更多評論
      

    # re: 紅黑樹的Java實現 2009-12-19 23:51 tcelvis
    還有一個不太理解的地方。為什么你的每個子類都要定義一個<E extends Comparable<E>>?這實際上不是把RBTree定義的<E extends Comparable<E>>給隱藏了么?直接引用RBTree已經定義的E不可以么?  回復  更多評論
      

    # re: 紅黑樹的Java實現 2010-07-25 15:26 姚朝文
    別忘了,你現在寫的東西,都是給國人看的多!不是對自己的英語很自信就拿來炫,最好給出中英注釋!  回復  更多評論
      

    # re: 紅黑樹的Java實現 2010-11-24 12:42 big
    @姚朝文
    連英文都不看你還寫什么code, 回家洗洗睡吧, 人家欠你的嗎?還好意思要中英注釋, 莫名其妙。  回復  更多評論
      

    # re: 紅黑樹的Java實現 2011-01-05 21:51 stxpascal
    package algorithms.tree 這個包在哪???  回復  更多評論
      

    # re: 紅黑樹的Java實現 2011-03-04 11:16 chs
    你腦門被夾了吧,看不懂不要看,照你這么說你在中國,那你學英語干屁啊,都是21世紀的人,國家提倡學習英語,你還在這里給國人看。2B @姚朝文
      回復  更多評論
      

    # re: 紅黑樹的Java實現[未登錄] 2013-01-05 14:39 大大
    干你媽比的,要么寫中文注釋,要么死回你媽比里去,會倆英文,拽尼瑪腿啊  回復  更多評論
      

    # re: 紅黑樹的Java實現 2014-02-02 16:47 new
    刪除部分的代碼貌似不對啊。
    如果刪除的是一個左右子樹都存在的節點,那么成分會先找到前序節點,并把cur指向該節點(該節點沒有右子樹存在)。
    接下來進入判斷,如果cur存在左子樹,把左子樹賦給cur的父節點。
    問題在于被刪除節點的父節點和cur之間沒有了關聯(沒有設置)。
    而且對于某些額情況,還會存在左子樹作為了被刪除節點的子樹。例如,對于深度為2的滿二叉樹,對左1添加子節點之后,刪除根節點的左節點。

    請樓主再仔細驗證一下。  回復  更多評論
      

    # re: 紅黑樹的Java實現 2014-02-26 20:27 super fly
    想問一下,這個是完整,直接能用的代碼嗎???好像是不怎么行耶?  回復  更多評論
      

    # re: 紅黑樹的Java實現 2014-02-26 20:38 super fly
    怎么找到這個DefaultBSTree和BSTree?。?#64;new  回復  更多評論
      


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 免费人成在线观看69式小视频| 亚洲大尺码专区影院| 女人18毛片特级一级免费视频 | 18禁超污无遮挡无码免费网站| 亚洲aⅴ天堂av天堂无码麻豆| 亚洲综合婷婷久久| 中文字幕亚洲电影| 国产免费午夜a无码v视频| 亚洲免费综合色在线视频| 免费女人高潮流视频在线观看 | 久久久久亚洲AV无码专区桃色| 岛国片在线免费观看| 四虎成年永久免费网站| 久久久久国产精品免费网站| aaa毛片免费观看| 一个人看的在线免费视频| 亚洲精品动漫免费二区| 亚洲人成色777777精品| 精品亚洲AV无码一区二区三区| 亚洲第一区视频在线观看| 亚洲一区二区三区电影| 亚洲国产精品一区| 亚洲电影国产一区| 亚洲AV日韩AV永久无码久久| 精品亚洲一区二区| 亚洲处破女AV日韩精品| 国产V亚洲V天堂无码久久久| 亚洲VA中文字幕无码毛片| 国产AV无码专区亚洲精品| 日本红怡院亚洲红怡院最新| 亚洲精品无码久久久久sm| 亚洲色欲一区二区三区在线观看| 在线观看亚洲成人| 久久亚洲国产午夜精品理论片| 亚洲成av人影院| 日产亚洲一区二区三区| 亚洲av无码片区一区二区三区| 亚洲国产91在线| 亚洲aⅴ天堂av天堂无码麻豆| 黄色片网站在线免费观看| av午夜福利一片免费看久久|