Java集合原始碼分析(十四):TreeMap

專注的阿熊發表於2021-05-24

刪除一個元素

我們看看 java 程式碼是怎麼實現的:

public V remove(Object key) {

     // 先用二分法獲取這個元素,如果為 null ,不需要繼續了

     Entry<K,V> p = getEntry(key);

     if (p == null)

         return null;

     V oldValue = p.value;

     deleteEntry(p);

     return oldValue;

}

private void deleteEntry(Entry<K,V> p) {

     modCount++;

     size--;

     // If strictly internal, copy successor's element to p and then make p

     // point to successor.

     // 如果 p 有兩個兒子,就把 p 指向它的後繼者,也就是它後邊的元素

     if (p.left != null && p.right != null) {

         Entry<K,V> s = successor(p);

         p.key = s.key;

         p.value = s.value;

         p = s;

     } // p has 2 children

     // Start fixup at replacement node, if it exists.

     // p 有一個兒子,外匯跟單gendan5.com或者沒有兒子,獲取到之後放在 replacement

     Entry<K,V> replacement = (p.left != null ? p.left : p.right);

     // p 有兒子

     if (replacement != null) {

         // Link replacement to parent

         // p 的子孫接在 p 的父級

         replacement.parent = p.parent;       

         //p 是根節點

         if (p.parent == null)

             root = replacement;

         //p 是左兒子

         else if (p == p.parent.left)

             p.parent.left  = replacement;

         // p 是右兒子

         else

             p.parent.right = replacement;

         // p 的連結都刪掉

         // Null out links so they are OK to use by fixAfterDeletion.

         p.left = p.right = p.parent = null;

         // Fix replacement

         if (p.color == BLACK)

             // 修正

             fixAfterDeletion(replacement);

     } else if (p.parent == null) { // return if we are the only node.

         root = null;

     } else {

         //p 沒有兒子

         //  No children. Use self as phantom replacement and unlink.

         if (p.color == BLACK)

             fixAfterDeletion(p);

         // 把其父節點連結到 p 的都去掉

         if (p.parent != null) {

             if (p == p.parent.left)

                 p.parent.left = null;

             else if (p == p.parent.right)

                 p.parent.right = null;

             p.parent = null;

         }

     }

}

修正調整的方法:

private void fixAfterDeletion(Entry<K,V> x) {

     while (x != root && colorOf(x) == BLACK) {

         // x 是左兒子

         if (x == leftOf(parentOf(x))) {

             // sib x 的兄弟

             Entry<K,V> sib = rightOf(parentOf(x));       

             // 兄弟是紅色的

             if (colorOf(sib) == RED) {

                 setColor(sib, BLACK);

                 setColor(parentOf(x), RED);

                 rotateLeft(parentOf(x));

                 sib = rightOf(parentOf(x));

             }          

             // 兄弟沒有孩子或者孩子是黑色的

             if (colorOf(leftOf(sib))  == BLACK &&

                 colorOf(rightOf(sib)) == BLACK) {

                 setColor(sib, RED);

                 x = parentOf(x);

             } else {

                 // 兄弟的右孩子是黑色的

                 if (colorOf(rightOf(sib)) == BLACK) {

                     setColor(leftOf(sib), BLACK);

                     setColor(sib, RED);

                     rotateRight(sib);

                     sib = rightOf(parentOf(x));

                 }

                 setColor(sib, colorOf(parentOf(x)));

                 setColor(parentOf(x), BLACK);

                 setColor(rightOf(sib), BLACK);

                 rotateLeft(parentOf(x));

                 x = root;

             }

         } else { // symmetric

             Entry<K,V> sib = leftOf(parentOf(x));

             if (colorOf(sib) == RED) {

                 setColor(sib, BLACK);

                 setColor(parentOf(x), RED);

                 rotateRight(parentOf(x));

                 sib = leftOf(parentOf(x));

             }

             if (colorOf(rightOf(sib)) == BLACK &&

                 colorOf(leftOf(sib)) == BLACK) {

                 setColor(sib, RED);

                 x = parentOf(x);

             } else {

                 if (colorOf(leftOf(sib)) == BLACK) {

                     setColor(rightOf(sib), BLACK);

                     setColor(sib, RED);

                     rotateLeft(sib);

                     sib = leftOf(parentOf(x));

                 }

                 setColor(sib, colorOf(parentOf(x)));

                 setColor(parentOf(x), BLACK);

                 setColor(leftOf(sib), BLACK);

                 rotateRight(parentOf(x));

                 x = root;

             }

         }

     }

 

     setColor(x, BLACK);

}


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69946337/viewspace-2773715/,如需轉載,請註明出處,否則將追究法律責任。

相關文章