jdk源碼分析紅/黑樹狀結構——插入篇

來源:互聯網
上載者:User

標籤:通過   紅色   步驟   map   private   修複   tco   png   jdk   

紅/黑樹狀結構是自平衡的排序樹,自平衡的優點是減少遍曆的節點,所以效率會高。如果是非平衡的二叉樹,當順序或逆序插入的時候,尋找動作很可能會遍曆n個節點紅/黑樹狀結構的規則很容易理解,但是維護這個規則難。一、規則1.每個節點要麼是紅色、要麼是黑色2.根節點一定是黑色3.紅色節點不可以連續出現(父節點、子節點不可同時為紅)4.從任意節點出發,到樹底的所有路線,途徑的黑節點數量必須相同在修改紅/黑樹狀結構的時候,切記要維護這個規則。一般預設插入紅色節點(除非是root節點),插入後再進行旋轉和顏色變換二、旋轉、變換技巧關於旋轉和顏色變換有幾種情況:1.插入root不會違反規則2.父黑插入節點的父節點是黑色,不會違反規則3.父紅插入節點的父節點是紅色,一定違反規則(違反規則3)(因為預設插入紅色節點),此時就需要修複紅/黑樹狀結構了。這種情況下又細分為幾種情況4.父紅,叔紅父節點和叔節點均為紅色(違反規則3)

這種情況下就把父節點和叔節點都改成黑色,然後曾節點改為紅色

可是此時,如果曾節點是根節點的話,那麼必須將曾節點轉為黑色。所以一般在修補紅/黑樹狀結構的方法的最後,會強制將根節點轉為黑色這種情況可能又會導致5.1的情況5.1父紅,叔黑,外側子孫父節點是紅色,叔節點是黑色或者null,且新增節點是曾節點的外側子孫(違反規則3)外側子孫:A點是B點的左-左-....-左或者右-右-..-右,那麼A是B的外側子孫,否則A是B的內側子孫符號解釋:N:新插入的節點,P:父節點,G:曾節點,U:叔節點

此時就需要將G點旋轉,這裡是右旋

不過此時顏色還有衝突,還要調整一下顏色將P與G的顏色對調,既P變為黑色,G變為紅色

總結一下,5.1的步驟:step1:P->黑step2:G->紅step3:將G旋轉5.1.1關於旋轉的方向旋轉有左旋右旋,具體是看父節點是曾節點的左節點還是右節點P是G的左節點,那麼就將G右旋(因為要把P移動到G的位置)P....G....右節點.....................G左旋5.2父紅,叔黑,內側子孫父節點是紅色,叔節點是黑色或者null,且新增節點是曾節點的內側子孫(違反規則3)外側子孫:A點是B點的左-左-....-左或者右-右-..-右,那麼A是B的外側子孫,否則A是B的內側子孫5.2跟5.1隻有一個內側外側的區別。內側子孫比外側要多做一次旋轉。目的是把內側子孫旋轉成外側子孫來做

這裡的N就是G的內側子孫,現在要把N變成G的外側子孫。將P旋轉(這裡是左旋),讓N旋轉到P的位置

之後的步驟就是和5.1處理外側子孫的一樣了。5.2.1內側轉外側的旋轉方向根據P點和N的相對位置,當N是P的右節點,則將P左旋,否則將P右旋目的是讓N旋轉到P的位置總結情況:1.插入的是根節點,不違反規則2.插入點的父節點是黑色,不違反規則3.插入點的父、叔節點是紅色,將父、叔轉成黑色,然後將曾節點轉成紅色4.插入點的父是紅色、叔節點是黑色或者null,通過旋轉和轉變顏色,注意內側外側子孫!三、分析TreeMap源碼jdk中的紅/黑樹狀結構實現是TreeMap。

每次put之後,都會調用這個方法去維護紅/黑樹狀結構的規則

    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) {//父、叔節點都是紅色,情況4                //將父節點和叔節點變為黑色,曾節點變為紅色                    setColor(parentOf(x), BLACK);                    setColor(y, BLACK);                    setColor(parentOf(parentOf(x)), RED);                    x = parentOf(parentOf(x));                } else {//父節點是紅色,叔節點是黑色或者null                    if (x == rightOf(parentOf(x))) {//內側子孫                        x = parentOf(x);                        rotateLeft(x);//旋轉成外側子孫                    }                    setColor(parentOf(x), BLACK);                    setColor(parentOf(parentOf(x)), RED);                    rotateRight(parentOf(parentOf(x)));//旋轉曾節點                }            } else {//父節點是曾節點的右節點                Entry<K,V> y = leftOf(parentOf(parentOf(x)));                if (colorOf(y) == RED) {                    setColor(parentOf(x), BLACK);                    setColor(y, BLACK);                    setColor(parentOf(parentOf(x)), RED);                    x = parentOf(parentOf(x));                } else {                    if (x == leftOf(parentOf(x))) {                        x = parentOf(x);                        rotateRight(x);                    }                    setColor(parentOf(x), BLACK);                    setColor(parentOf(parentOf(x)), RED);                    rotateLeft(parentOf(parentOf(x)));                }            }        }        root.color = BLACK;//強制將根節點轉成黑色}



查看原文:http://blog.zswlib.com/2016/11/01/jdk%e6%ba%90%e7%a0%81%e5%88%86%e6%9e%90%e7%ba%a2%e9%bb%91%e6%a0%91-%e6%8f%92%e5%85%a5%e7%af%87/

jdk源碼分析紅/黑樹狀結構——插入篇

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.