紅黑樹學(xué)習(xí)及Java實(shí)現(xiàn)

BST

二叉查找樹(Binary Search Tree,簡(jiǎn)稱BST)是一棵二叉樹测僵,它的左子節(jié)點(diǎn)的值比父節(jié)點(diǎn)的值要小街佑,右節(jié)點(diǎn)的值要比父節(jié)點(diǎn)的值大。它的高度決定了它的查找效率捍靠。

image

在理想的情況下舆乔,二叉查找樹增刪查改的時(shí)間復(fù)雜度為O(logN)(其中N為節(jié)點(diǎn)數(shù)),最壞的情況下為O(N)剂公。當(dāng)它的高度為logN+1時(shí)希俩,我們就說二叉查找樹是平衡的。

BST存在的問題

BST存在的主要問題是纲辽,數(shù)在插入的時(shí)候會(huì)導(dǎo)致樹傾斜颜武,不同的插入順序會(huì)導(dǎo)致樹的高度不一樣,而樹的高度直接的影響了樹的查找效率拖吼。理想的高度是logN鳞上,最壞的情況是所有的節(jié)點(diǎn)都在一條斜線上,這樣的樹的高度為N吊档。

RBTree

基于BST存在的問題篙议,一種新的樹——平衡二叉查找樹(Balanced BST)產(chǎn)生了。平衡樹在插入和刪除的時(shí)候怠硼,會(huì)通過旋轉(zhuǎn)操作將高度保持在logN鬼贱。其中兩款具有代表性的平衡樹分別為AVL樹和紅黑樹。AVL樹由于實(shí)現(xiàn)比較復(fù)雜香璃,而且插入和刪除性能差这难,在實(shí)際環(huán)境下的應(yīng)用不如紅黑樹。

紅黑樹(Red-Black Tree葡秒,以下簡(jiǎn)稱RBTree)的實(shí)際應(yīng)用非常廣泛姻乓,比如Linux內(nèi)核中的完全公平調(diào)度器嵌溢、高精度計(jì)時(shí)器、ext3文件系統(tǒng)等等蹋岩,各種語言的函數(shù)庫(kù)如Java的TreeMap和TreeSet赖草,C++ STL的map、multimap剪个、multiset等秧骑。

RBTree也是函數(shù)式語言中最常用的持久數(shù)據(jù)結(jié)構(gòu)之一,在計(jì)算幾何中也有重要作用禁偎。值得一提的是腿堤,Java 8中HashMap的實(shí)現(xiàn)也因?yàn)橛肦BTree取代鏈表阀坏,性能有所提升如暖。

RBTree的定義

RBTree的定義如下:

1. 任何一個(gè)節(jié)點(diǎn)都有顏色,黑色或者紅色

2. 根節(jié)點(diǎn)是黑色的

3. 父子節(jié)點(diǎn)之間不能出現(xiàn)兩個(gè)連續(xù)的紅節(jié)點(diǎn)忌堂,但是可以出現(xiàn)連續(xù)的黑色節(jié)點(diǎn)

4. 任何一個(gè)節(jié)點(diǎn)向下遍歷到其子孫的葉子節(jié)點(diǎn)盒至,所經(jīng)過的黑節(jié)點(diǎn)個(gè)數(shù)必須相等

5. 空節(jié)點(diǎn)被認(rèn)為是黑色的

RBTree在理論上還是一棵BST樹,但是它在對(duì)BST的插入和刪除操作時(shí)會(huì)維持樹的平衡士修,即保證樹的高度在[logN,logN+1](理論上枷遂,極端的情況下可以出現(xiàn)RBTree的高度達(dá)到2*logN,但實(shí)際上很難遇到)棋嘲。這樣RBTree的查找時(shí)間復(fù)雜度始終保持在O(logN)從而接近于理想的BST酒唉。RBTree的刪除和插入操作的時(shí)間復(fù)雜度也是O(logN)。RBTree的查找操作就是BST的查找操作沸移。

RBTree的旋轉(zhuǎn)操作

旋轉(zhuǎn)操作(Rotate)的目的是使節(jié)點(diǎn)顏色符合定義痪伦,讓RBTree的高度達(dá)到平衡。

Rotate分為left-rotate(左旋)和right-rotate(右旋)雹锣,區(qū)分左旋和右旋的方法是:待旋轉(zhuǎn)的節(jié)點(diǎn)從左邊上升到父節(jié)點(diǎn)就是右旋网沾,待旋轉(zhuǎn)的節(jié)點(diǎn)從右邊上升到父節(jié)點(diǎn)就是左旋。即蕊爵,左旋節(jié)點(diǎn)的父節(jié)點(diǎn)點(diǎn)從左邊下沉成為子節(jié)點(diǎn)為左旋辉哥,右旋節(jié)點(diǎn)的父節(jié)點(diǎn)從右邊下沉成為子節(jié)點(diǎn)為右旋

image

RBTree的查找操作

參考樹:二叉樹

RBTree的插入操作

RBTree的插入與BST的插入方式是一致的,只不過是在插入過后攒射,可能會(huì)導(dǎo)致樹的不平衡醋旦,這時(shí)就需要對(duì)樹進(jìn)行旋轉(zhuǎn)操作和顏色修復(fù)(在這里簡(jiǎn)稱插入修復(fù)),使得它符合RBTree的定義会放。

新插入的節(jié)點(diǎn)是紅色的浑度,插入修復(fù)操作如果遇到父節(jié)點(diǎn)的顏色為黑則修復(fù)操作結(jié)束。也就是說鸦概,只有在父節(jié)點(diǎn)為紅色節(jié)點(diǎn)的時(shí)候是需要插入修復(fù)操作的箩张。

插入修復(fù)操作分為以下的三種情況甩骏,而且新插入的節(jié)點(diǎn)的父節(jié)點(diǎn)都是紅色的:

叔叔節(jié)點(diǎn)也為紅色。

叔叔節(jié)點(diǎn)為空先慷,且祖父節(jié)點(diǎn)饮笛、父節(jié)點(diǎn)和新節(jié)點(diǎn)處于一條斜線上。

叔叔節(jié)點(diǎn)為空论熙,且祖父節(jié)點(diǎn)福青、父節(jié)點(diǎn)和新節(jié)點(diǎn)不處于一條斜線上。

插入操作-case 1

case 1的操作是將父節(jié)點(diǎn)和叔叔節(jié)點(diǎn)與祖父節(jié)點(diǎn)的顏色互換脓诡,這樣就符合了RBTRee的定義无午。即維持了高度的平衡,修復(fù)后顏色也符合RBTree定義的第三條祝谚。下圖中宪迟,操作完成后A節(jié)點(diǎn)變成了新的節(jié)點(diǎn)。如果A節(jié)點(diǎn)的父節(jié)點(diǎn)不是黑色的話(所以需要向上遍歷所有節(jié)點(diǎn)顏色)交惯,則繼續(xù)做修復(fù)操作次泽。

image

插入操作-case 2

case 2的操作是將B節(jié)點(diǎn)進(jìn)行右旋操作,并且和父節(jié)點(diǎn)A互換顏色席爽。通過該修復(fù)操作RBTRee的高度和顏色都符合紅黑樹的定義意荤。如果B和C節(jié)點(diǎn)都是右節(jié)點(diǎn)的話,只要將操作變成左旋就可以了只锻。

image

插入操作-case 3

case 3的操作是將C節(jié)點(diǎn)進(jìn)行左旋玖像,這樣就從case 3轉(zhuǎn)換成case 2了,然后針對(duì)case 2進(jìn)行操作處理就行了齐饮。case 2操作做了一個(gè)右旋操作和顏色互換來達(dá)到目的捐寥。如果樹的結(jié)構(gòu)是下圖的鏡像結(jié)構(gòu),則只需要將對(duì)應(yīng)的左旋變成右旋沈矿,右旋變成左旋即可上真。

image

插入操作的總結(jié)

插入后的修復(fù)操作是一個(gè)向root節(jié)點(diǎn)回溯的操作,一旦牽涉的節(jié)點(diǎn)都符合了紅黑樹的定義羹膳,修復(fù)操作結(jié)束睡互。之所以會(huì)向上回溯是由于case 1操作會(huì)將父節(jié)點(diǎn),叔叔節(jié)點(diǎn)和祖父節(jié)點(diǎn)進(jìn)行換顏色陵像,有可能會(huì)導(dǎo)致祖父節(jié)點(diǎn)不平衡(紅黑樹定義3)就珠。這個(gè)時(shí)候需要對(duì)祖父節(jié)點(diǎn)為起點(diǎn)進(jìn)行調(diào)節(jié)(向上回溯)。

祖父節(jié)點(diǎn)調(diào)節(jié)后如果還是遇到它的祖父顏色問題醒颖,操作就會(huì)繼續(xù)向上回溯妻怎,直到root節(jié)點(diǎn)為止,根據(jù)定義root節(jié)點(diǎn)永遠(yuǎn)是黑色的泞歉。在向上的追溯的過程中逼侦,針對(duì)插入的3中情況進(jìn)行調(diào)節(jié)匿辩。直到符合紅黑樹的定義為止。直到牽涉的節(jié)點(diǎn)都符合了紅黑樹的定義榛丢,修復(fù)操作結(jié)束铲球。

如果上面的3中情況如果對(duì)應(yīng)的操作是在右子樹上,做對(duì)應(yīng)的鏡像操作就是了晰赞。

刪除節(jié)點(diǎn)

刪除操作首先需要做的也是BST的刪除操作稼病,刪除操作會(huì)刪除對(duì)應(yīng)的節(jié)點(diǎn),如果是葉子節(jié)點(diǎn)就直接刪除掖鱼,如果是非葉子節(jié)點(diǎn)然走,會(huì)用對(duì)應(yīng)的中序遍歷后繼節(jié)點(diǎn)來頂替要?jiǎng)h除節(jié)點(diǎn)的位置。刪除后就需要做刪除修復(fù)操作戏挡,使的樹符合紅黑樹的定義芍瑞,符合定義的紅黑樹高度是平衡的。

刪除修復(fù)操作在遇到被刪除的節(jié)點(diǎn)是紅色節(jié)點(diǎn)或者到達(dá)root節(jié)點(diǎn)時(shí)增拥,修復(fù)操作完畢啄巧。

刪除修復(fù)操作是針對(duì)刪除黑色節(jié)點(diǎn)(葉子節(jié)點(diǎn)為紅色節(jié)點(diǎn))才有的寻歧,當(dāng)黑色節(jié)點(diǎn)被刪除后會(huì)讓整個(gè)樹不符合RBTree的定義的第四條掌栅。需要做的處理是從兄弟節(jié)點(diǎn)上借調(diào)黑色的節(jié)點(diǎn)過來,如果兄弟節(jié)點(diǎn)沒有黑節(jié)點(diǎn)可以借調(diào)的話码泛,就只能往上追溯猾封,將每一級(jí)的黑節(jié)點(diǎn)數(shù)減去一個(gè),使得整棵樹符合紅黑樹的定義噪珊。

刪除操作的總體思想是從兄弟節(jié)點(diǎn)借調(diào)黑色節(jié)點(diǎn)使樹保持局部的平衡晌缘,如果局部的平衡達(dá)到了,就看整體的樹是否是平衡的痢站,如果不平衡就接著向上追溯調(diào)整磷箕。

代碼引申

CompareTo 和 equals 和 == 區(qū)別

CompareTo

CompareTo 比較兩個(gè)類對(duì)象。就不能直接通過>,<進(jìn)行比較阵难,引用對(duì)象不是基本數(shù)據(jù)類型岳枷。兩個(gè)對(duì)象進(jìn)行比較返回 “0”是 相等,正數(shù)是 大于呜叫,負(fù)數(shù)是小于

==

當(dāng)復(fù)合數(shù)據(jù)類型用(==)進(jìn)行比較空繁,比較的是他們?cè)趦?nèi)存中的存放地址。

equals

當(dāng)復(fù)合數(shù)據(jù)類型之間進(jìn)行equals比較時(shí)朱庆,這個(gè)方法的初始行為是比較對(duì)象在堆內(nèi)存中的地址盛泡,但在一些諸如String,Integer,Date類中把Object中的這個(gè)方法覆蓋了,作用被覆蓋為比較內(nèi)容是否相同娱颊。

Java 中 比較兩個(gè)類對(duì)象傲诵。就不能直接通過>,<進(jìn)行比較凯砍,引用對(duì)象不是基本數(shù)據(jù)類型

Java中很多類也都有CompareTo方法,甚至于排序算法的底層組成也是依賴于比較的拴竹,而這個(gè)比較就是依賴于各種數(shù)據(jù)類型的CompareTo或者Compare方法果覆。Java中所有的compareTo方法都源于一個(gè)共同的接口,那就是Comparable殖熟。這個(gè)接口只有一個(gè)方法局待,那就是CompareTo。所有想要具有比較功能的類菱属,都建議實(shí)現(xiàn)這個(gè)接口钳榨,而非是自己定義這個(gè)功能,這是面向?qū)ο蟮母拍睿▽⒕哂邢嗤δ艿氖挛锍橄蟮揭粋€(gè)共同的類或接口)纽门,并且為了多態(tài)也建議通過實(shí)現(xiàn)接口來進(jìn)行向上轉(zhuǎn)型薛耻,通過接口來操作具體實(shí)現(xiàn),這也是面向接口編程要求我們做的赏陵。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末饼齿,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蝙搔,更是在濱河造成了極大的恐慌缕溉,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吃型,死亡現(xiàn)場(chǎng)離奇詭異证鸥,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)勤晚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門枉层,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人赐写,你說我怎么就攤上這事鸟蜡。” “怎么了挺邀?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵揉忘,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我悠夯,道長(zhǎng)癌淮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任沦补,我火速辦了婚禮乳蓄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘夕膀。我一直安慰自己虚倒,他們只是感情好美侦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著魂奥,像睡著了一般菠剩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上耻煤,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天具壮,我揣著相機(jī)與錄音,去河邊找鬼哈蝇。 笑死棺妓,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的炮赦。 我是一名探鬼主播怜跑,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼吠勘!你這毒婦竟也來了性芬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤剧防,失蹤者是張志新(化名)和其女友劉穎植锉,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诵姜,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡汽煮,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年搏熄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了棚唆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡心例,死狀恐怖宵凌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情止后,我是刑警寧澤瞎惫,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站译株,受9級(jí)特大地震影響瓜喇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜歉糜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一乘寒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧匪补,春花似錦伞辛、人聲如沸烂翰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽甘耿。三九已至,卻和暖如春竿滨,著一層夾襖步出監(jiān)牢的瞬間佳恬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工于游, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留殿怜,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓曙砂,卻偏偏與公主長(zhǎng)得像头谜,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鸠澈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 紅黑樹是平衡二叉查找樹的一種柱告。為了深入理解紅黑樹,我們需要從二叉查找樹開始講起笑陈。 BST 二叉查找樹(Binary...
    kanehe閱讀 1,376評(píng)論 0 8
  • 引自:https://zhuanlan.zhihu.com/p/24367771Java代碼實(shí)現(xiàn) 紅黑樹是平衡二叉...
    Magic11閱讀 222評(píng)論 0 0
  • 注:本文對(duì)網(wǎng)上一些博客進(jìn)行詳細(xì)與修正际度,并給出C語言實(shí)現(xiàn) 紅黑樹是平衡二叉查找樹的一種。為了深入理解紅黑樹涵妥,我們需要...
    molscar閱讀 420評(píng)論 0 2
  • 紅黑樹(英語:Red–black tree)是一種自平衡二叉查找樹乖菱,是在計(jì)算機(jī)科學(xué)中用到的一種數(shù)據(jù)結(jié)構(gòu),典型的用途...
    卡巴拉的樹閱讀 15,209評(píng)論 11 113
  • 紅黑樹 紅黑樹也是一種自平衡的二叉搜索樹以前也叫做平衡二叉B樹(Symmetric Binary B-tree) ...
    ducktobey閱讀 771評(píng)論 0 1