雖是讀書筆記,可是如轉載請註明出處 http://segmentfault.com/blog/exploring/
.. 拒絕伸手複製黨html
如下是算法導論第十八章的學習筆記算法
若是紅黑樹中的每一個黑結點吸取它的紅子女,並把它們的子女併入自身,描述這個結果的數據結構。
(2-3-4樹
)
or
假設將一棵紅黑樹的每個紅結點 「吸取」 到它的黑色父結點中,來讓紅結點的子女變成黑色父結點的子女(忽略關鍵字的變化)。當一個黑結點的全部紅色子女都被吸取後,其可能的度是多少?此結果樹的葉子深度怎樣segmentfault
這段整理自July's blog 和 本身的理解
磁盤讀取數據(把數據從外存調入內存)是以盤塊(block)爲基本單位的。位於同一盤塊中的全部數據都能被一次性所有讀取出來。而磁盤IO代價主要花費在查找時間上。所以咱們應該儘可能將相關信息存放在同一盤塊,同一磁道中,這樣一次IO時間就能夠。或者至少放在同一柱面或相鄰柱面上,以求在讀/寫信息時儘可能減小磁頭來回移動的次數,避免過多的查找時間。數據結構
因此,在大規模數據存儲方面,大量數據存儲在外存磁盤中,而在外存磁盤中讀取/寫入塊(block)中某數據時,首先須要定位到磁盤中的某塊,如何有效地查找磁盤中的數據,須要一種合理高效的外存數據結構,B 樹是爲了磁盤或其它存儲設備而設計的一種多叉平衡查找樹。函數
與紅黑樹不一樣之處在於,B樹的節點能夠有許多個,從幾個到幾千個。不過 B 樹與紅黑樹同樣,一棵含 n 個結點的 B 樹的高度也爲 O(logn)
,但可能比一棵紅黑樹的高度小許多,由於對數的底由紅黑樹的2
變爲t
(t爲最小度數
). 由於它的分支因子比較大。因此,B 樹能夠在 O(logn)
時間內,實現各類如插入(insert),刪除(delete)等動態集合操做。學習
B樹的每一個節點根據實際狀況能夠包括大量信息和子女(固然是不能超過磁盤塊的大小,由於咱們從磁盤上讀取信息的時候通常都是按照磁盤塊進行的,一個磁盤快對應一個節點,每次檢索B樹的時候遇到一個節點,也就對應一次磁盤的訪問操做,若是一個節點大於了一個磁盤塊,那麼訪問一個節點須要兩次磁盤訪問,效率就不行了,通常塊的大小在 1k~4k 左右 )spa
如圖 17是磁盤文件名;小紅方塊表示這個 17 文件內容在硬盤中的存儲位置;p1 表示指向 17 左子樹的指針設計
若是是一棵 m 階的 B 樹,那麼有:指針
m
階樹的孩子數ceil(m / 2)
個孩子(其中 ceil(x) 是一個取上限的函數);B 樹的類型和節點定義以下圖所示:
code
假如每一個盤塊能夠正好存放一個 B 樹的結點(正好存放 2 個文件名)。那麼一個 BTNODE 結點就表明一個盤塊,而子樹指針就是存放另一個盤塊的地址。
下面,我們來模擬下查找文件 29 的過程:(詳細見July博客)
分析上面的過程,發現須要 3 次磁盤 IO 操做和 3 次內存查找 操做。關於內存中的文件名查找,因爲是一個有序表結構,能夠利用折半查找提升效率。至於 IO 操做是影響整個 B 樹查找效率的決定因素。
查詢須要O(h)
存取的磁盤頁面數
插入元素 - 檢查是否存在
- 存在,不插入
- 不存在,在葉子節點插入新的元素
葉子節點空間足夠(#<m-1
),插入
葉子節點空間不夠(#=m-1
),插入進去,而後分裂
,中間節點上移
若是致使父節點滿了,父節點再分裂;若致使根節點滿了。這樣致使樹的高度
+1
高度爲h
的樹,只須要O(h)
次磁盤存取操做。
刪除元素 - 檢查BTree是否存在該節點
- 不存在,不刪除
- 存在,刪除之,而後判斷:該元素是否有左右孩子
如有,則上移``孩子
中相近元素 (「左孩子最右邊的節點」 或 「右孩子最左邊的節點」) 到該節點 - to step *
若無,直接刪除 , - to step *
step *: 若是刪除以後或者移動以後,致使某節點的元素數目小於 ceil(m/2)-1
;則須要查看某相鄰的兄弟節點是否豐滿
(大於 ceil(m/2)-1
)
step *1. 父節點降低
一個關鍵字到該節點;降低
--判斷兄弟 --
step *2.1 若是其某個相鄰兄弟
結點中比較豐滿(元素個數大於 ceil(m/2)-1
),則能夠借給父結點一個元素,即將最豐滿的相鄰兄弟結點中上移
到父節點中 上調
step *2.2 若是其相鄰兄弟
都剛脫貧,即借了以後其結點數目小於 ceil(m/2)-1
,則該結點與其相鄰的某一兄弟結點進行 合併
成一個結點,以此來知足條件 合併