HashMap中保證紅黑樹根節點一定是對應鏈表頭節點moveRootToFront()方法源碼解讀

紅黑樹根節點若不爲其對應鏈表的頭節點,則按照下述步驟的處理,將根節點向前移動到頭節點:

  1. 將根節點從所在鏈表中刪除,即鏈表的刪除操作:修改根節點的前後節點的指向即可,即將根節點的上一節點的下一節點設置爲根節點的下一節點,將根節點的下一節點的上一節點設置爲根節點的上一節點。
  2. 將根節點所在鏈表的頭節點位置的值設置爲根節點;
  3. 將現有頭節點的上一個節點設置爲根節點,將根節點的下一個節點設置爲現有頭節點,將根節點的上一個節點設置爲null.
    具體源碼如下:
/**HashMap$TreeNode的moveRootToFront()方法源碼*/
        /*** Ensures that the given root is the first node of its bin.*/
        static <K,V> void moveRootToFront(Node<K,V>[] tab, TreeNode<K,V> root) {
            int n;
            if (root != null && tab != null && (n = tab.length) > 0) { 
                int index = (n - 1) & root.hash;
                TreeNode<K,V> first = (TreeNode<K,V>)tab[index]; //目前的頭節點
                if (root != first) {//根節點不等於目前的頭節點
                    Node<K,V> rn;
                    tab[index] = root; //將根節點設置爲頭節點
                    TreeNode<K,V> rp = root.prev;
                    if ((rn = root.next) != null)
                        ((TreeNode<K,V>)rn).prev = rp; //將根節點的下一節點的上一節點指向根節點的上一節點
                    if (rp != null)
                        rp.next = rn; //將根節點的上一節點的下一節點指向根節點的下一節點
                    if (first != null)
                        first.prev = root; //將原頭節點的上一節點指向根節點
                    root.next = first; //將根節點的下一節點指向原頭節點
                    root.prev = null; //將根節點的上一節點設爲null
                }
                assert checkInvariants(root); //檢查根節點是否滿足紅黑樹節點規則
            }
        }

示意圖:
將紅黑樹的根節點移動到對應鏈表頭節點,假設根節點所處位置如下左圖所示,初始鏈表指向爲實線,調整指向的線爲虛線;調整後的鏈表指向如下右圖所示:
在這裏插入圖片描述
PS:由於文檔是我在本地編寫好之後再賦值過來的,有些文本格式沒能完整的體現,故提供下述圖片,供大家閱覽,以便有更好的閱讀體驗:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章