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

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

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

    E81086713E446D36F62B2AA2A3502B5EB155

    Java雜家

    雜七雜八。。。一家之言

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

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


    下面是代碼:

    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 閱讀(8498) 評論(20)  編輯  收藏

    Feedback

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    請樓主再仔細(xì)驗證一下。  回復(fù)  更多評論
      

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

    # re: 紅黑樹的Java實現(xiàn) 2014-02-26 20:38 super fly
    怎么找到這個DefaultBSTree和BSTree啊?@new  回復(fù)  更多評論
      


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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 无限动漫网在线观看免费| 久久免费福利视频| 日韩视频在线免费| 亚洲人成色在线观看| 无人在线直播免费观看| 亚洲av无码国产综合专区| 精品久久久久成人码免费动漫| 91午夜精品亚洲一区二区三区| 久久午夜免费视频| 亚洲欧洲日产国码www| 91精品免费在线观看| 亚洲第一页在线视频| 7m凹凸精品分类大全免费| 亚洲欧洲精品一区二区三区| 99xxoo视频在线永久免费观看| 亚洲黄色免费观看| 99re热免费精品视频观看| 亚洲色偷偷偷综合网| 亚洲AV蜜桃永久无码精品| 亚洲人成网站在线观看播放| 亚洲已满18点击进入在线观看| 香蕉高清免费永久在线视频 | 日韩亚洲国产二区| 曰韩无码AV片免费播放不卡| 亚洲成A人片在线观看WWW| 69pao强力打造免费高清| 亚洲欧美日本韩国| 青青草原亚洲视频| 91免费国产自产地址入| 久久精品国产亚洲av瑜伽| 精品亚洲一区二区三区在线观看| 久久精品私人影院免费看| 国产午夜亚洲精品| 亚洲综合色自拍一区| 99久久久精品免费观看国产| 免费精品视频在线| 4444亚洲国产成人精品| 国产一级淫片免费播放| 久久爰www免费人成| 久久亚洲精品高潮综合色a片| 亚洲AV无码乱码国产麻豆穿越 |