看了這麼多篇紅黑樹文章,你都理解了嘛?

2021-01-07 愚公要移山1

很早之前就想寫一篇關於紅黑樹的文章,但是由於擔心自己理解的不透徹,就一直不敢下筆。於是在重新看了很多篇文章和資料之後,決定徹徹底底的把紅黑樹搞清楚。也希望讓你在面試中遊刃有餘。OK,廢話不多說,開始今天的文章。

整篇文章的思路是這樣的,紅黑樹其實就是一種數據結構,設計它的目的就是為了高效地進行增刪改查,所以我們文章的順序也會按照這個思路來進行。我們先從二叉查找樹逐漸引入到紅黑樹,然後再詳細的講解。你如果看過其他文章想必也一定清楚,紅黑樹比較麻煩,希望你有點耐心,認真理解每一張圖再往下分析。

一、二叉查找樹

在正式開始了解紅黑樹之前呢,我們先來看一下二叉查找樹的概念,從淺入深,希望你不要著急,下面就是是一顆二叉查找樹:

從這張圖我們會發現如下的規律:

(1)左子樹上所有節點的值均小於或等於它的根結點的值。

(2)右子樹上所有節點的值均大於或等於它的根結點的值。

如果我們想要查找一個數字11,過程是怎麼樣的呢?

上面的過程已經很清晰了,在查找的時候,先與根節點比較,比根節點大則從右子樹查找,比根節點小則從左子樹查找,然後重複上面的過程,一直到找到我們需要的元素為止。

這個過程是查找操作,對於添加和刪除呢?其實原理也是一樣的,我們第一步就是找到我們需要插入的位置,然後把元素插入即可。這樣看二叉查找樹挺好的呀?別著急我們繼續往下看這種情況。

如果我們在剛剛開始的時候還是以9為根節點,然後依次插入13、15、17、19。我們看會發生什麼情況:

好好地一棵樹變成了這個鬼樣子,成了「一邊倒」了。這時候再去查找19呢?

這效率也太低下了吧,一顆二叉查找樹的優勢完全喪失了。怎麼辦呢?既然上面的二叉查找樹在插入的時候變成了「一條腿」,也就是喪失了平衡,那我們乾脆做出一點改進,使用平衡二叉樹吧。

二、平衡二叉樹

下面就是一顆平衡二叉樹。

上面這顆二叉樹就是平衡二叉樹,也叫作AVL樹。仔細分析你會發現如下特點:

(1)從任何一個節點出發,左右子樹深度之差的絕對值不超過1。

(2)左右子樹仍然為平衡二叉樹。

現在我們再往裡插入一個元素4,這時候會發生什麼呢?

從圖中我們可以看到,插入了4之後破壞了平衡,怎麼辦呢?既然破壞了平衡,那就想辦法糾正過來。

我們發現經過調整之後,我們二叉樹就重新回到了平衡。對於其他插入的情況,大家可以自己私下試一遍,最終你會發現一個結論,那就是平衡二叉樹在插入時最多只需要兩次旋轉就會重新恢復平衡。

從上面這個過程我們會發現,平衡二叉樹真的很不錯,在查找時既有著二叉查找樹的優越性,在插入時還能通過調整繼續保持著。那麼為什麼還要使用到紅黑樹呢?我覺得可以從以下兩個方面來考慮:

(1)刪除:對於平衡二叉樹來說,在最壞情況下,需要維護從被刪節點到根節點這條路徑上所有節點的平衡性,旋轉的量級是O(logN)。但是紅黑樹就不一樣了,最多只需3次旋轉就會重新平衡,旋轉的量級是O(1)。

(2)保持平衡:平衡二叉樹高度平衡,這也就意味著在大量插入和刪除節點的場景下,平衡二叉樹為了保持平衡需要調整的頻率會更高。

注意:在大量查找的情況下,平衡二叉樹的效率更高,也是首要選擇。在大量增刪的情況下,紅黑樹是首選。

鑑於以上原因,因此我們才使用到了紅黑樹這種更好的結構。上面提了這麼多次紅黑樹,相信你已經迫不及待的想要認識一下了。下面就正式拉開紅黑樹的序幕。

三、紅黑樹

紅黑樹聽名字就知道,裡面涉及到兩種顏色:紅色和黑色。我們直接來看一下:

上面這張圖就是紅黑樹,你會發現他有如下特徵(下面的特徵最好看一個特徵重新看一遍紅黑樹):

(1)每個節點只有兩種顏色:紅色和黑色。

(2)根節點是黑色的。

(3)每個葉子節點(NIL)都是黑色的空節點。

(4)從根節點到葉子節點,不會出現兩個連續的紅色節點。

(5)從任何一個節點出發,到葉子節點,這條路徑上都有相同數目的黑色節點。

這五條就是紅黑樹的特徵,你每看一個特徵最好重新看一遍圖,這樣可以加深理解。這五條特徵看起來真的很複雜,不過正是由於這些複雜的特徵才保證了紅黑樹的良好特性。如何保證的呢?我們從增刪改查四個角度來一個一個分析一下:

1、查詢節點

查詢節點是最簡單的一個,他的查找過程和二叉查找樹一樣,查找元素比當前節點大,就從右子樹繼續查找比較,查找元素比當前節點小,就從左子樹繼續查找比較。查找過程就不再贅述了。

2、插入節點

插入節點是最麻煩的一個,它分為三種情況。我們一種一種看,這樣比較有條理性。

第一種情況:新節點沒有父節點

沒有父節點只有一種情況,就是插入的節點是整棵樹第一個節點,也就是根節點,為此我們只需要把插入節點塗成黑色就OK了。這也就保證了性質2:根節點是黑色的。

第二種情況:新節點的父節點是黑色

為此我們舉一個例子,比如說上面的紅黑樹中,我們插入節點14。來看一下會發生什麼情況?

這種情況我們發現新插入節點14的父節點就是黑色的。現在為了保證紅黑樹的性質,我們對照每個特性來檢查一遍。只要有一條不滿足,我們都需要調整。我們重新對照之後會發現每一條都符合。此時不需要調整。

第三種情況:新節點的父親節點為紅色

我們還是舉個例子,比如我們在最開始的紅黑樹基礎之上插入節點21,此時會發生什麼情況呢?

此時還是老規矩,對照著紅黑樹的5個特徵一個一個來看,只要是違反了一條就需要做出調整。我們來看一下:

(1)每個節點只有兩種顏色:紅色和黑色。這一條滿足。

(2)根節點是黑色的。這一條也滿足。

(3)每個葉子節點(NIL)都是黑色的空節點。這一條滿足。

(4)從根節點到葉子節點,不會出現兩個連續的紅色節點。這一條發現不滿足。

就是上面這一條規則沒有滿足,所以我們此時需要調整?問題來了如何調整呢?因為直接看父節點沒辦法實現,所以還需要觀察另外的節點,也就是新節點的叔叔節點。根據叔叔節點的顏色來調整。調整的方式有兩種:變色和旋轉。

(1)叔叔節點是紅色:

此時插入的節點是21,但是叔叔節點是27,更好是紅色。我們直接來看調整的步驟:

第一步:把新節點21的父節點22變成黑色。

此時重新看一下是否滿足紅黑樹的五條特徵了沒,一條一條發現,第五條沒有滿足,也就是從任何一個節點出發,到葉子節點,這條路徑上沒有相同數目的黑色節點。比如從25出發。這時候怎麼辦呢?那就繼續調整。

第二步:把22的父節點25變成紅色

這時候還是老規矩,不要嫌棄麻煩,因為只有經歷了一步又一步的麻煩之後,你才能牢記那5條規則特徵。我們對照之後會發現節點25和節點27是兩個連續的紅色節點,這時候又破壞了規則4。怎麼辦呢?那就繼續調整就OK了。

難道這時候還要繼續往上調整嗎?如果你這樣做就錯了,因為不斷地往上調整最後就會把根節點變成了紅色,會走進死胡同。我們往下走。

第三步:把節點27變成黑色

來吧,繼續重新審查那5條規則特徵。很明顯節點17和節點25是兩個連續的紅色,又破壞了。是不是心太累了,調整了這麼久,還是沒有保證那5條規則,感覺是不是還沒有平衡二叉樹好。如果你現在有這種感覺,我只能說,希望你繼續堅持下去,勝利就在眼前。

第四步:把節點17和節點18都變成黑色節點

來來來,現在你再對照一下那5條規則,是不是完全保證了。寫到這真的是太累了,和你讀這篇文章的感覺一樣一樣的,不過這種情況也只是插入情況中的一種。繼續往下看:

(1)叔叔節點是黑色:

這種情況下又分了兩種情況:

第一種情況:新插入節點為父節點的左孩子

第二種情況:新插入節點為父節點的右孩子

按照第一遍的思路,我們對這兩種情況執行同樣的操作,最終也能保證紅黑樹的5條特徵。

到了這一步,插入操作的所有情況就講解完畢。另外關於左旋和右旋的知識我在這裡不再說明了,因為你看到了紅黑樹這個程度,相信也一定看過平衡二叉樹。左旋右旋哪幾種情況,都會有介紹到。

3、刪除節點

紅黑樹的刪除說實話更加的複雜,如果你看過算法導論的話應該能明白一點,我們在這裡也進行一個大概的講解。

刪除大致分了三種情況,

(1)第一種情況:要刪除的節點有零個子節點

這種情況下最簡單,也就是刪除的是根節點或者是葉子節點(這裡的葉子節點都是指非NULL的葉子節點),根節點直接刪除即可。如果葉子節點是紅色的,也可以直接刪除,如果葉子節點是黑色的,那麼就需要進行調整,調整的步驟和插入時調整的步驟一樣。

(2)第二種情況:要刪除的節點有一個子節點

這時候。把子節點的值替換掉要刪除的節點的值。

現在我們的5把11替換掉之後,又回到了第一種情況。如果節點5是紅色的,可以直接刪除,如果節點5是黑色的,那麼就需要進行調整,此時的節點5就是葉子節點。調整的步驟和插入時調整的步驟一樣。

(3)第三種情況:要刪除的節點有兩個子節點

現在刪除的節點有兩個子節點,同樣的我們可以執行第二種情況的操作,

若節點13之前是葉子節點,那就和第一種情況一樣了,如果節點13是紅色的,可以直接刪除,如果節點13是黑色的,那麼就需要進行調整,此時的節點13就是葉子節點。調整的步驟和插入時調整的步驟一樣。

若節點13之前還有子節點,那就和第二種情況一樣了。那就繼續替換和判斷。

以上呢就是刪除的情況,最後一種情況是修改,這種情況是查找和插入的結合體,也就是先找到要修改的元素,修改完值之後,繼續進行調整即可。

現在還有最後一個問題了,都說紅黑樹很重要,為什麼重要呢?我們來看一下使用場景。

四、使用場景

紅黑樹的應用真的是太多了,比如說java中的HashMap和TreeMap。還有就是linux也經常使用到。這種數據結構在面試的時候是一個常問問題,希望大家能夠明白和理解。如何用java手撕紅黑樹,在後續文章中我會添加。如有問題還請批評指正。

相關焦點

  • 車主快看,為什麼那麼多車都不辦ETC?這篇文章來給你答案!
    車主快看,為什麼那麼多車都不辦ETC?這篇文章來給你答案!對於有人不願意辦ETC這個問題,只能說在這些人身邊沒有一個因為使用ETC而體會到其便利性的朋友。說起黑科技,我國也絕對是很盛產,畢竟地大物博,人才濟濟,而ETC絕對是這些黑科技中備受好評的一個,至於說為什麼將ETC劃做黑科技一類,畢竟它的出現改變了人們的一種傳統繳費模式,同時因為它的便利性,在推廣以後就備受好評,並最終發展到擁有更多受眾群體,可以說ETC絕對是一種成功的繳費方式。
  • 看了這篇連中國人都無語的中文文章,歪果仁們徹底崩潰了!
    這篇文章特點在。。你讀一遍就知道了。。估計也沒人能聽懂,因為通篇都是同音字,發音都是shi,但這又確實是一篇文章。。百科解釋:「石頭屋子裡有一個詩人姓施,喜歡獅子,發誓要吃掉十頭獅子。這位先生經常去市場尋找獅子。這一天十點鐘的時候他到了市場,正好有十頭大獅子也到了市場。
  • 什麼是紅黑樹?程式設計師面試必問!
    balabala了這麼多,相信你對紅黑樹有一定印象了,那麼現在來考考你:思考題1:黑結點可以同時包含一個紅子結點和一個黑子結點嗎? (答案見文末)接下來先講解紅黑樹的查找熱熱身。因為如果叔叔結點為黑結點,而父結點為紅結點,那么叔叔結點所在的子樹的黑色結點就比父結點所在子樹的多了,這不滿足紅黑樹的性質5。後續情景同樣如此,不再多做說明了。前文說了,需要旋轉操作時,肯定一邊子樹的結點多了或少了,需要租或借給另一邊。插入顯然是多的情況,那麼把多的結點租給另一邊子樹就可以了。
  • 看完這4個文章排版要點,你就會排版啦!
    1/ 什麼是公眾號文章排版 /先給大家看幾篇公眾號文章:①③請問大家,上面的文章都有排版嘛?答案當然是肯定的!你猶豫個啥所以,現在回過頭來,看看文章一開始的幾篇文章排版,他們的排版都很好。因為不管好不好看,他們的文章都很有用。
  • 看了這麼多篇提升語文成績的文章,發現有個重點一直沒說...
    但是,看了這麼多篇提升語文成績的文章,發現有個重點一直沒說,為什麼我平常的閱讀量也不少,我記錄的好詞好句也有了厚厚的幾本,可是我的語文成績還是沒有明顯的提升呢?今天就為大家詳細分析一下,到底怎樣積累,怎樣總結,怎樣的學習習慣,才能真正產生效果,才能切實的提升語文成績,這就是重點!
  • 沒有比這篇文章講得再清楚的了
    說到景深,很多人應該都了解是什麼。但是如果你不明白,看這篇文章前,您要明白什麼是景深。我們之前也講過想要背景虛化明顯就要用大光圈+長焦+對焦距離近這三者來搞定。因為我們知道小光圈+廣角鏡頭是獲得遠近都清晰的好方法,但是真的要是對焦到很遠的地方,你會發現景深雖然大了,遠處更清晰了,但是近處卻模糊了。有沒有這麼一個對焦距離是我對焦的時候對在這裡,能獲得最大的景深範圍呢?有!這個使用拍攝方法就叫超焦距攝影。首先我們所有的說法都是在某個固定的光圈和固定的焦距作為前提的。
  • 為什麼別人的文章有料又有趣,而你的文章卻乾巴巴像個蔫茄子?
    當然,我們作為普通人,可能沒有想過想到要去治國興邦,我們就想寫出自己喜歡、他人愛看的文字,悅己及人,順便也能夠提高自身競爭力。現在有句話不是這麼講嘛:「會做不如會講,會講不如會寫」。除了寫作「四度」,《寫作7堂課》這本書種還詳細介紹了從知識點到關鍵詞,從泛閱讀到主題知識樹閱讀,從「刷屏閱讀」到開機閱讀,從跟蹤趨勢到跟蹤行業,從輸入信息到輸出信息的各種聯機搜索小竅門。還有搜金句、素材標題、微信公眾號文章、群聊記錄或朋友圈的各種技巧。 秋葉大叔為了讓大家理解更透徹,還用實例演示了寫作缺各種東西怎麼辦?
  • 看完這篇文章,再罵這套分性別的教輔書也不遲
    估計出版社可能也覺得這是一個比較新穎的教輔方向,所以在這套書出版之後,「華師教輔ECNUP」公眾號前後寫了兩篇文章來介紹這套教輔。但我想來想去還是覺得有點疑惑,所以去網上翻出來那篇仔仔細細地讀了幾遍。(因為這兩篇文章現在都打不開了,所以我只能用網上轉載的部分來進行閱讀理解,有可能文中引用的家長評論,和標題所用的家長評論,不是同一位家長。
  • 我,鉛筆 | 花點時間讀完這篇文章,你不會後悔的.
    後來是你的習慣造就了你  」    貝 才 先 生這篇文章,一經問世,哄傳至今,已成經典。▲FEE官網上的「我,鉛筆」全篇文章以第一人稱的擬人視角,講述了一根鉛筆是如何在「看不見的手」的作用下,通過自由人的奇妙組合,從原木、石墨、黃銅、黑鎳、橡膠等材料,變成一支書寫流利的鉛筆的故事。
  • 樹|突然間,看了這篇文章,樹我懂了!
    它的左子樹不為空,並且左子樹的所有節點值都要小於跟節點的值。 平衡二叉樹 平衡二叉樹具有以下性質他是一顆控訴或者他的左右兩個子樹的高度差絕對值不超過1,並且左右兩個子樹都是一顆平衡二叉樹。
  • 做網絡直播如何成為網紅?你可能需要看這篇文章
    現在做網絡直播的人是越來越多,有的是全職做的,當然也有兼職做的,全職做網絡直播的都是那些大網紅,動輒幾百萬上千萬的粉絲,各大平臺拿著高額籤約費談,而一些兼職的網絡主播,就是有著自己的工作,而到了晚上或者空閒時間來進行直播,賺一些收入,而等做起來之後,有平臺願意籤約,那麼兼職主播也會轉為全職主播
  • 含淚看完這篇文章
    我問他叫什麼,他說他叫紅,想成為一名元素戰士。他還給我介紹了三位朋友,分別是藍、黃和黑。認識了他們後,紅想讓我加入他們去尋找他爺爺沒找到的寶藏,我爽快地答應了。但找了這麼久,半點線索都沒找著,我只好去找紅,他家門是開的,我問了一聲就進去了,見到一個小盒子,打開后里面放起了一首美妙的歌曲,蓋子還刻著一棵大柳樹。我聽到有聲音從我背後飄來,紅竟然在哭,「對不起」,我輕輕地對他說。
  • 海尼曼、紅火箭、RAZ、牛津樹......分級讀物這麼多,給孩子選哪個最合適?
    紅火箭基礎級很適合孩子入門使用。海尼曼一經推出,就受到了廣泛的歡迎,和紅火箭是同一個作者:Pam Holden 帕姆·霍爾頓。海尼曼是英國哈考特教育出版公司的作品,這家公司的產品都比較注重專業性和可用性,海尼曼一共有300本,主題涵蓋人物、自然、地理等,初級階段多圖少字。
  • 黑松露為什麼這麼的貴?看完這篇文章你就知道了!
    夢賢野生黑松露 黑松露是一種長於地下的野生食用真菌,氣味十分特殊,難以形容,口感沒有白松露那麼辛辣,但香味更加醇厚。此外黑松露還具有一種類似於泥土的清香,同時又具備魚湯的鮮美。 黑松露因為散發著特殊的氣味,自古便有許多人為之著迷。
  • 如何選擇白、黃、黑三種顏色?看完這篇文章你會明白的
    對於我們每個人來說,不同的膚色是要選擇顏色的,如果膚色和衣服的顏色搭配得很合適,他會讓你錦上添花、如果沒有合理搭配,就不會特別好看了。因此小編針對這個問題,就來告訴大家如何選擇白、黃、黑三種顏色的女生。
  • 賞了這麼多年紅葉,你可能都沒見過真的「楓樹」
    圖片:harum.koh / Flickr曉來誰染霜林醉看了槭樹的圖,你可能會問,這不就是楓樹嗎?為什麼要叫這麼一個怪名字?的確,槭樹屬的很多植物都被稱為「楓樹」,不過「楓」這個字,最早指的是金縷梅科的楓香樹(Liquidambar formosana)。
  • 教你做便當的文章太多了,看這一篇頂一百篇!
    這篇文章,和那些隨便教你幾道便當菜的文章,不一樣。我們把做好便當的步驟、細節裡裡外外扒了個遍!這篇文章裡,你能學到:💡 如何規劃一周的便當食譜💡 可以節省50%時間的食材預處理方法💡 便當菜的通用烹飪原則💡 裝盒技巧和如何選購適合自己的便當盒花五分鐘看完,恭喜,你的便當技能樹就點滿了。
  • 黑嘛嘛(仿原麥山丘)
    我是原麥山丘的忠實粉絲,前幾天給我媽買了黑嘛嘛,吃了一口非常喜歡那種不甜膩但是很濃鬱得黑芝麻味。而且黑芝麻確實非常有營養,所以在網上找了找配方。這次做了一次山寨版本的原麥山丘黑嘛嘛。需要的步驟和材料都比較多,請務必仔細閱讀小貼士。
  • 你永遠想不到,只看《故事會》的鳳姐寫文章這麼厲害 | 愛範兒
    不過從羅玉鳳在鳳凰新聞客戶端上發表的幾篇文章來看,寫得還真是不錯,尤其是幾篇寫自己在紐約生活的文章,感情真摯,文字也很流暢。而在《有一隻雞在我面前,我絕對跑不過它》這篇中,我們也才知道,在羅玉鳳的學生時代,其實並不像自己所說的那樣只愛看一些市井雜誌,相反,她喜歡泡在學校閱覽室看書。
  • 看了這篇文章,你還想當網紅嗎?
    今天在家裡休息,本來都準備停更一天,為了下面的幾篇爆文做準備,可沒想到,老肖一個電話打過來,先是抱怨了幾句,後面直接開始罵起來了。原來,他感覺疫情期間直播比較賺錢,還能出名,他就抱著試一試的態度在招聘網站上投遞了簡歷,想去做網紅。我一聽就覺得特別好笑,不是貶低他,一身200斤的豬肉,一個頭重腳輕的腦袋,在加上一個火爆不堪的牛脾氣,就這樣還想做「網紅」,我一聽就樂了。