数据结构里的一棵树
一、樹(shù)是什么?
有根有枝葉便是樹(shù)!根只有一個(gè),枝葉可以有,也可以沒(méi)有,可以有一個(gè),也可以有很多。
就像這樣:
嗯,應(yīng)該是這樣:
二、一些概念
1、高度
樹(shù)有多高,嗯,我一米八三!
樹(shù)的高度怎么算?
高度是啥,就是從下往上到最頂端,從葉節(jié)點(diǎn)到根節(jié)點(diǎn)。
從每個(gè)葉節(jié)點(diǎn)開(kāi)始,一個(gè)節(jié)點(diǎn)一個(gè)節(jié)點(diǎn)往上數(shù),數(shù)到根節(jié)點(diǎn),最長(zhǎng)的那個(gè)數(shù)就是數(shù)的高度。葉節(jié)點(diǎn)起始為0.
上面這個(gè)樹(shù)的高度是4。
2、深度
深度,顧名思義,就是從上往下到最低端,從根節(jié)點(diǎn)到葉節(jié)點(diǎn)。
從根開(kāi)始,一個(gè)節(jié)點(diǎn)一個(gè)節(jié)點(diǎn)往下數(shù),數(shù)到每個(gè)葉子節(jié)點(diǎn),最長(zhǎng)的那個(gè)數(shù)就是數(shù)的深度。根節(jié)點(diǎn)的起始為0.
上面這個(gè)樹(shù)的深度是4。
對(duì)比上面的高度,看到了哈,數(shù)值是一樣的,
3、層
一層是什么呢。就是橫向的同一高度的所有節(jié)點(diǎn)湊一塊兒就是一層。
像下面一條線(xiàn)連接了第二層所有的節(jié)點(diǎn):
三、二叉樹(shù)的遍歷
二叉樹(shù)是什么?
二叉樹(shù)就是每個(gè)節(jié)點(diǎn)最多有兩個(gè)分叉子節(jié)點(diǎn)。
遍歷是什么意思?
遍歷就是一個(gè)樹(shù)的所有節(jié)點(diǎn)都點(diǎn)一遍,那么既然要點(diǎn)一遍,總歸要遵循一個(gè)特定的順序,不然,亂來(lái)的話(huà)總會(huì)可能漏一個(gè),或者多一個(gè)。
像下面這棵樹(shù):
1、前序遍歷
順序:中左右
中 6 -> 左中 5 -> 左 2 -> 右 3 -> 右中 7 -> 右 8
結(jié)果就是:6、5、2、3、7、8。
2、中序遍歷
順序:左中右
左 2 -> 中 5 -> 右 3 -> 中 6 -> 右中 7 -> 右 8
結(jié)果就是: 2、5、3、6、7、8。
3、后序遍歷
順序:左右中
左 2 -> 右 3 -> 中左 5 -> 右 8 -> 中右 7 -> 中 6
結(jié)果就是:2、3、5、8、7、6.
這個(gè)順序,其實(shí)很容易混亂。想要記得牢,只需要一點(diǎn):
【前、中、后】,前為左,右為后,哪個(gè)順序遍歷,那么哪個(gè)節(jié)點(diǎn)就會(huì)順序居中,其它的節(jié)點(diǎn),靠左的居前。
節(jié)點(diǎn)的巡查是從根節(jié)點(diǎn)出發(fā),從上到下,從左至右巡查,每個(gè)節(jié)點(diǎn)及其子點(diǎn)巡查完畢后,再跳出到其它節(jié)點(diǎn)。
4、附加:層序遍歷
層序遍歷很簡(jiǎn)單就是從上到下,一層一層的收攏節(jié)點(diǎn)。
第一層 6 -> 第二層 5、7 -> 第三層 2、3、8
結(jié)果就是:6、5、7、2、3、8.
4、樹(shù)能干什么?
樹(shù)能蓋房子!
沒(méi)錯(cuò),樹(shù)通常用來(lái)搭建存儲(chǔ)數(shù)據(jù)的房子。
數(shù)據(jù)存儲(chǔ)是對(duì)數(shù)據(jù)的持久化保存,針對(duì)數(shù)據(jù)的操作包括讀和寫(xiě)。不過(guò),無(wú)論是讀還是寫(xiě),都離不開(kāi)對(duì)數(shù)據(jù)的檢索操作。
1、B樹(shù)
之前文章介紹過(guò)B樹(shù)及在數(shù)據(jù)庫(kù)存儲(chǔ)方面的應(yīng)用:
你好,我是B樹(shù)
MySQL InnoDB 是怎么使用 B+ 樹(shù)存數(shù)據(jù)的?
B 樹(shù),即balance tree。其結(jié)構(gòu)及節(jié)點(diǎn)數(shù)據(jù)分布遵循特定的規(guī)則。
B 樹(shù)的算法運(yùn)行時(shí)間通常由它所執(zhí)行的【磁盤(pán)讀寫(xiě)操作次數(shù)】決定,所有一般會(huì)一次盡可能的讀寫(xiě)更多的信息。一個(gè)B樹(shù)節(jié)點(diǎn)通常和一個(gè)完整的磁盤(pán)頁(yè)大小相同,所以磁盤(pán)頁(yè)的大小限制了一個(gè)B樹(shù)節(jié)點(diǎn)所能包含孩子節(jié)點(diǎn)的個(gè)數(shù)。
B 樹(shù)每個(gè)節(jié)點(diǎn)會(huì)包含多少個(gè)分支,稱(chēng)之為分支因子。分支因子越大,B 的高度越低,查找關(guān)鍵字所需的磁盤(pán)存取次數(shù)越少,查詢(xún)時(shí)間越短。這也是為什么會(huì)推崇使用B樹(shù)結(jié)構(gòu)來(lái)作為數(shù)據(jù)底層存儲(chǔ)。
2、二叉搜索樹(shù)
二叉搜索樹(shù)是以一棵二叉樹(shù)來(lái)組織數(shù)據(jù)存儲(chǔ),每個(gè)節(jié)點(diǎn)除了包含數(shù)據(jù)本身外,還包括指向左節(jié)點(diǎn)、右節(jié)點(diǎn)及父節(jié)點(diǎn)的指針,即key、left、right、p。其中存儲(chǔ)數(shù)據(jù)需滿(mǎn)足左中右非降序存儲(chǔ),即left.key <= key <= right.key。
左中右,是不是很熟悉,就是我們上面講到過(guò)的【中序遍歷】順序?!局行虮闅v】輸出的話(huà),整個(gè)數(shù)列會(huì)是非降序排序數(shù)列。
搜索樹(shù)結(jié)構(gòu)通常支持包括查找,最大值,最小值,插入,刪除等操作。嗯,這些操作是不是又很熟悉,總之就是一個(gè)【日常操作】。
二叉搜索樹(shù)上的操作時(shí)間和它的高度成正比,對(duì)于n節(jié)點(diǎn)二叉樹(shù),通常最壞運(yùn)行時(shí)間為O(lgn)(為什么是O(lgn)呢?這個(gè)需要推導(dǎo),先記住就行了),這個(gè)就是樹(shù)元素隨機(jī)分步的情況下的結(jié)果。極端情況下,一條鏈從根到葉的話(huà),時(shí)間固定就是O(n)了。就像下面這個(gè)棵樹(shù):
3、紅黑樹(shù)
紅黑樹(shù)也是一個(gè)二叉搜索樹(shù)。那為什么會(huì)需要這么一棵樹(shù)呢?
就是為了避免上面哪種極端或者接近極端情況的出現(xiàn)。它可以【保證最壞的情況下操作時(shí)間復(fù)雜度為O(lgn)】。
對(duì)的,是保證!那怎么保證呢?當(dāng)然是通過(guò)維持紅黑樹(shù)本身的結(jié)構(gòu)特點(diǎn)來(lái)實(shí)現(xiàn)。
我們上面及到過(guò)二叉搜索樹(shù)節(jié)點(diǎn)包含的數(shù)據(jù),紅黑樹(shù)會(huì)在其基礎(chǔ)上增加一個(gè)存儲(chǔ)位來(lái)表示節(jié)點(diǎn)的顏色(紅或者黑)。通過(guò)【對(duì)任何一條從根到葉子節(jié)點(diǎn)的簡(jiǎn)單路徑上的各個(gè)節(jié)點(diǎn)顏色進(jìn)行約束】來(lái)確?!緵](méi)有一路徑會(huì)比其它路徑長(zhǎng)2倍】。
紅黑樹(shù)的特點(diǎn):
-
a)【節(jié)點(diǎn)要么紅,要么黑】
-
b)【根節(jié)點(diǎn)是黑的】
-
c)【葉節(jié)點(diǎn)是黑的】
-
d)【如果一個(gè)節(jié)點(diǎn)是紅色的,那么它的子節(jié)點(diǎn)是黑色的】
-
e)【對(duì)任何一個(gè)節(jié)點(diǎn),從該節(jié)點(diǎn)到其所有后代葉節(jié)點(diǎn)的簡(jiǎn)單路徑上的黑節(jié)點(diǎn)數(shù)據(jù)是相同的】
這里有個(gè)點(diǎn)需要強(qiáng)調(diào)一下,紅黑樹(shù)里所說(shuō)的葉子節(jié)點(diǎn)指的是【外部節(jié)點(diǎn)】,也就是不包含 key 的節(jié)點(diǎn)。
黑高:從某個(gè)節(jié)點(diǎn)到達(dá)其葉節(jié)點(diǎn)的【任何一個(gè)(參考e】簡(jiǎn)單路徑上的黑色節(jié)點(diǎn)個(gè)數(shù)稱(chēng)之為黑高。紅黑樹(shù)的黑高即為其根節(jié)點(diǎn)的黑高。
一顆有 n 個(gè)內(nèi)部節(jié)點(diǎn)的紅黑樹(shù)的高度至多為 2lg(n+1),也即我們前面說(shuō)的能夠保證最壞的情況下操作時(shí)間復(fù)雜度為O(lgn)。
紅黑樹(shù)有哪些應(yīng)用呢?
最常見(jiàn)的就是 HashMap了,用于解決存儲(chǔ)元素哈希沖突,當(dāng)鏈表元素個(gè)數(shù)超過(guò)8時(shí),即轉(zhuǎn)為紅黑樹(shù)。
總結(jié)
- 上一篇: Unity3d_Rewired官方文档翻
- 下一篇: 你真的会用 npx 吗❓❓❓