日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

图解集合8:红黑树的移除节点操作

發布時間:2024/6/21 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图解集合8:红黑树的移除节点操作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

紅黑樹移除節點

上文詳細講解了紅黑樹的概念,紅黑樹的插入及旋轉操作,根據測試代碼建立起來的紅黑樹結構為:

本文先研究一下紅黑樹的移除操作是如何實現的,移除操作比較復雜,具體移除的操作要進行幾次旋轉和移除的節點在紅黑樹中的位置有關,這里也不特意按照旋轉次數選擇節點了,就找三種位置舉例演示紅黑樹移除操作如何進行:

  • 移除根節點,例子就是移除節點30
  • 移除中間節點,例子就是移除節點70
  • 移除最底下節點,例子就是移除節點85

首先來過一下TreeMap的remove方法:

1 public V remove(Object key) { 2 Entry<K,V> p = getEntry(key); 3 if (p == null) 4 return null; 5 6 V oldValue = p.value; 7 deleteEntry(p); 8 return oldValue; 9 }

第2行的代碼是獲取待移除的節點Entry,做法很簡單,拿key與當前節點按指定算法做一個比較獲取cmp,cmp=0表示當前節點就是待移除的節點;cmp>0,取右子節點繼續比較;cmp<0,取左子節點繼續比較。

接著重點跟一下第7行的deleteEntry方法:

1 private void deleteEntry(Entry<K,V> p) { 2 modCount++; 3 size--; 4 5 // If strictly internal, copy successor's element to p and then make p 6 // point to successor. 7 if (p.left != null && p.right != null) { 8 Entry<K,V> s = successor(p); 9 p.key = s.key; 10 p.value = s.value; 11 p = s; 12 } // p has 2 children 13 14 // Start fixup at replacement node, if it exists. 15 Entry<K,V> replacement = (p.left != null ? p.left : p.right); 16 17 if (replacement != null) { 18 // Link replacement to parent 19 replacement.parent = p.parent; 20 if (p.parent == null) 21 root = replacement; 22 else if (p == p.parent.left) 23 p.parent.left = replacement; 24 else 25 p.parent.right = replacement; 26 27 // Null out links so they are OK to use by fixAfterDeletion. 28 p.left = p.right = p.parent = null; 29 30 // Fix replacement 31 if (p.color == BLACK) 32 fixAfterDeletion(replacement); 33 } else if (p.parent == null) { // return if we are the only node. 34 root = null; 35 } else { // No children. Use self as phantom replacement and unlink. 36 if (p.color == BLACK) 37 fixAfterDeletion(p); 38 39 if (p.parent != null) { 40 if (p == p.parent.left) 41 p.parent.left = null; 42 else if (p == p.parent.right) 43 p.parent.right = null; 44 p.parent = null; 45 } 46 } 47 }

用流程圖整理一下這里的邏輯:

下面結合實際代碼來看下。

?

移除根節點

根據上面的流程圖,根節點30左右子節點不為空,因此要先選擇繼承者,選擇繼承者的流程為:

分點整理一下移除節點30做了什么:

  • 由于節點30的右子節點不為空,因此從節點70開始不斷取左子節點直到取到葉子節點為止,最終取到的節點s為節點50
  • p的key=s的key即50,p的value=s的value即50,由于此時p指向的是root節點,因此root節點的key和value變化,變為50-->50
  • p=s,即p原來指向的是root節點,現在p指向s節點,p與s指向同一份內存空間,即節點50
  • 接著選擇replacement,由于p與s指向同一份內存空間,因此replacement判斷的是s是否有左子節點,顯然s沒有,因此replacement為空
  • replacement為空,但是p有父節點,因此可以判斷出來p也就是節點50不是root節點
  • 接著根據流程圖可知,節點p是一個紅色節點,這里不需要進行移除數據修正
  • 最后節點p是其父節點的左子節點,因此節點p的左子節點置為null,再將p的父節點置為null,相當于把節點p移除
  • 經過上述流程,移除根節點30之后的數據結構如下圖:

    ?

    移除中間節點

    接著看一下移除中間節點TreeMap是怎么做的,這里以移除節點70為例,繼續分點整理一下移除節點70做了什么:

  • 節點70有左右子節點,因此還是選擇繼承者,由于節點70的右子節點85沒有左子節點,因此選出來的繼承者就是節點85
  • p的key=s的key即85,p的value=s的value即85,此時p指向的是節點70,因此節點70的key與value都變為85
  • key與value賦值完畢后執行p=s,此時p指向節點85
  • 接著選擇replacement,由于85沒有左右子節點,因此replacement為null
  • replacement為null且節點p即節點85有父節點,根據流程圖可知,節點p是一個黑色節點,因此需要進行刪除數據修正
  • 最后節點p是其父節點的右子節點,因此節點p的右子節點置為null,再將p的父節點置為null,相當于把節點p移除
  • 總體流程和移除根節點差不多,唯一的區別是節點85是一個黑色節點,因此需要進行一次刪除數據修正操作。刪除數據修正實現為fixAfterDeletion方法,它的源碼:

    1 private void fixAfterDeletion(Entry<K,V> x) { 2 while (x != root && colorOf(x) == BLACK) { 3 if (x == leftOf(parentOf(x))) { 4 Entry<K,V> sib = rightOf(parentOf(x)); 5 6 if (colorOf(sib) == RED) { 7 setColor(sib, BLACK); 8 setColor(parentOf(x), RED); 9 rotateLeft(parentOf(x)); 10 sib = rightOf(parentOf(x)); 11 } 12 13 if (colorOf(leftOf(sib)) == BLACK && 14 colorOf(rightOf(sib)) == BLACK) { 15 setColor(sib, RED); 16 x = parentOf(x); 17 } else { 18 if (colorOf(rightOf(sib)) == BLACK) { 19 setColor(leftOf(sib), BLACK); 20 setColor(sib, RED); 21 rotateRight(sib); 22 sib = rightOf(parentOf(x)); 23 } 24 setColor(sib, colorOf(parentOf(x))); 25 setColor(parentOf(x), BLACK); 26 setColor(rightOf(sib), BLACK); 27 rotateLeft(parentOf(x)); 28 x = root; 29 } 30 } else { // symmetric 31 Entry<K,V> sib = leftOf(parentOf(x)); 32 33 if (colorOf(sib) == RED) { 34 setColor(sib, BLACK); 35 setColor(parentOf(x), RED); 36 rotateRight(parentOf(x)); 37 sib = leftOf(parentOf(x)); 38 } 39 40 if (colorOf(rightOf(sib)) == BLACK && 41 colorOf(leftOf(sib)) == BLACK) { 42 setColor(sib, RED); 43 x = parentOf(x); 44 } else { 45 if (colorOf(leftOf(sib)) == BLACK) { 46 setColor(rightOf(sib), BLACK); 47 setColor(sib, RED); 48 rotateLeft(sib); 49 sib = leftOf(parentOf(x)); 50 } 51 setColor(sib, colorOf(parentOf(x))); 52 setColor(parentOf(x), BLACK); 53 setColor(leftOf(sib), BLACK); 54 rotateRight(parentOf(x)); 55 x = root; 56 } 57 } 58 } 59 60 setColor(x, BLACK); 61 }

    方法第3行~第30行與第30行~第57行是對稱的,因此只分析一下前半部分也就是第3行~第30行的代碼。第三行的代碼"x == leftOf(parentOf(x))"很顯然判斷的是x是否其父節點的左子節點。其流程圖為:

    從上圖中,首先可以得出一個重要的結論:紅黑樹移除節點最多需要三次旋轉

    先看一下刪除數據修正之前的結構圖:

    p指向右下角的黑色節點85,對此節點進行修正,上面的流程圖是p是父節點的左子節點的流程,這里的p是父節點的右子節點,沒太大區別。

    sib取父節點的左子節點即節點60,節點60是一個黑色節點,因此這里不需要進行一次旋轉。

    接著,sib的左右子節點不是黑色節點且sib的左子節點為紅色節點,因此這里只需要進行一次旋轉的流程:

  • 將sib著色為它父節點的顏色
  • p的父節點著色為黑色
  • sib的左子節點著色為黑色
  • p的父節點右旋
  • 經過這樣四步操作之后,紅黑樹的結構變為:

    最后一步的操作在fixAfterDeletion方法的外層,節點85的父節點不為空,因此將節點85的父節點置空,最終移除節點70之后的數據結構為:

    ?

    移除最底下節點

    最后看看移除最底下節點的場景,以移除節點85為例,節點85根據代碼以節點p稱呼。

    節點p沒有左右子節點,因此節點p不需要進行選擇繼承者的操作;同樣的由于節點p沒有左右子節點,因此選擇出來的replacement為null。

    接著由于replacement為null但是節點p是一個黑色節點,黑色節點需要進行刪除修正流程:

  • 節點p是父節點的右子節點,那么節點sib為父節點的左子節點50
  • sib是黑色的,因此不需要進行一次右旋
  • sib的左子節點是紅色的,因此這里需要進行的操作是將sib著色為p父節點的顏色紅色、將p的父節點著色為黑色、將sib的左子節點著色為黑色、將p的父節點進行一次右旋
  • 這么做之后,樹形結構變為:

    最后還是一樣,回到fixAfterDeletion方法外層的代碼,將p的父節點置為null,即節點p就不在當前數據結構中了,完成移除,紅黑樹最終的結構為:

    ?

    轉載于:https://www.cnblogs.com/xrq730/p/6882018.html

    總結

    以上是生活随笔為你收集整理的图解集合8:红黑树的移除节点操作的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 噜噜吧噜噜色 | 亚洲国产精品久久久久爰性色 | 亚洲影院一区 | 中国大陆高清aⅴ毛片 | 欧美一区二区三区在线观看 | av在线播放免费 | 超碰伊人网 | 超碰在线伊人 | 免费成人福利视频 | 国产大片一区二区三区 | 日美韩一区二区三区 | 人妻少妇精品中文字幕av蜜桃 | 一区二区色 | 欧美色图一区 | 女同爱爱视频 | 免费久久一级欧美特大黄 | 国产欧美一级片 | 国产精品天美传媒 | 欧美黑人又粗又大高潮喷水 | 国产亚洲精品网站 | 色综合色综合色综合 | 欧美自拍视频在线观看 | 欧美三区在线观看 | 婷婷狠狠干 | 一本不卡 | 婷婷狠狠干| 美女扒开尿口让男人捅爽 | 欧美a网站| 一级伦理农村妇女愉情 | 亚欧色视频 | 涩色视频 | 日韩天堂在线视频 | www.夜夜操 | 少妇人妻偷人精品无码视频新浪 | 天堂网中文在线 | 亚洲a视频在线 | 一本大道一区二区 | 91视频久久 | 久久久久国产精品无码免费看 | 99久久精品免费看国产四区 | 97香蕉碰碰人妻国产欧美 | 91尤物视频 | 国产成人在线观看免费 | 韩国主播青草55部完整 | 成人黄页网站 | 日韩女优网站 | 国产成人一区二区三区别 | 无码人妻精品一区二区三区在线 | 国产久草视频 | 美女黄页网站 | 国产成人在线观看网站 | 久久99久久99精品免视看婷婷 | 在线免费观看av网站 | www.xxx日韩 | 波多野在线观看 | 成人免费毛片观看 | 免费观看黄色的网站 | 女女爱爱视频 | 国产精品亚洲一区二区三区在线观看 | 色姑娘天天操 | 国产青青草 | 少妇福利在线 | 哪里可以看免费毛片 | 中文字幕三区 | 日韩一区二区欧美 | 午夜激情啪啪 | 久久免费成人 | 四虎影库永久在线 | 色鬼久久| 亚洲黄色免费视频 | 亚洲av无码不卡一区二区三区 | 3d动漫精品h区xxxxx区 | 亚洲成人自拍网 | 插插看 | 国产8区 | 手机看片1024欧美 | 8x8x永久免费视频 | 99色播| 欧美日韩3p | 91欧美日韩麻豆精品 | 三级五月天| gai免费观看网站外网 | 大度亲吻原声视频在线观看 | 黄色第一网站 | 一区二区在线播放视频 | 中文字幕一区2区3区 | 国产羞羞| 精品人妻码一区二区三区红楼视频 | 特黄一级毛片 | 卡一卡二在线视频 | 涩涩网站在线看 | 日屁视频 | 91亚洲国产成人精品一区二三 | 亚洲精品99久久久久中文字幕 | 欧美jizzhd精品欧美18 | 中文字幕日韩精品无码内射 | 草逼导航| 黄色片怎么看 | 成人毛片视频在线观看 |