紅黑樹根節點若不爲其對應鏈表的頭節點,則按照下述步驟的處理,將根節點向前移動到頭節點:
- 將根節點從所在鏈表中刪除,即鏈表的刪除操作:修改根節點的前後節點的指向即可,即將根節點的上一節點的下一節點設置爲根節點的下一節點,將根節點的下一節點的上一節點設置爲根節點的上一節點。
- 將根節點所在鏈表的頭節點位置的值設置爲根節點;
- 將現有頭節點的上一個節點設置爲根節點,將根節點的下一個節點設置爲現有頭節點,將根節點的上一個節點設置爲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:由於文檔是我在本地編寫好之後再賦值過來的,有些文本格式沒能完整的體現,故提供下述圖片,供大家閱覽,以便有更好的閱讀體驗: