本文將爲你們介紹B樹和B+樹,首先介紹了B樹的應用場景,爲何須要B樹;而後介紹了B樹的查詢和插入過程;最後談了B+樹針對B樹的改進。
在談B樹以前,先說一下B樹所針對的應用場景。那麼B樹是用來作什麼的呢? B樹是一種爲輔助存儲設計的一種數據結構,廣泛運用在數據庫和文件系統中。舉個例子來講,數據庫你們確定都不陌生,好比如今有一張表,其中有100萬條記錄,如今要查找查找其中的某條數據,如何快速地從100萬條記錄中找到須要的那條記錄呢?你們的第一反應確定是二叉查找樹,下面先談談爲何二叉樹不行。算法
仍是剛剛那個例子,如今一張表中有100萬條記錄,咱們以表的主鍵來構建一個二叉查找樹。先不考慮二叉樹不平衡退化成鏈表的狀況,假設是理想狀況,這個二叉樹是徹底平衡的。那麼構建完成以後應該是下面這個樣子的(示意圖)
樹的高度應該爲
如今開始查找,加入咱們要查找值爲100的節點,怎麼找呢?首先應該獲取樹的根節點。通常來講,表的索引自己也很大,不可能所有存儲在內存中,所以索引每每以索引文件的形式存儲的磁盤上。也就是說咱們構建的二叉查找樹太大了,內存放不下,通常要存在磁盤上,用的時候再從磁盤讀入到內存。如今假設咱們知道了根節點所在的磁盤位置,那麼應該首先將根節點讀入內存中,這裏進行了一次IO操做,而後判斷要找的值比根節點大仍是小,100比4大,因此去右子樹查找。那麼如何找到6所在的節點呢?根節點中存儲着6所在節點在磁盤上存放的位置。一樣,須要將其先讀入內存中,而後再判斷繼續向下查找,這裏又是一次IO操做。下面的過程相似,再也不展開。總結一下,查找到咱們所需的那條記錄大概須要進行20次IO操做,也就是樹的高度,由於每向下查找一層,就要進行一次IO操做。
爲何要強調IO操做,而不是在內存中比較的次數呢? 由於磁盤的速度相比內存而言是很是的慢。好比常見的7200RPM的硬盤,搖臂轉一圈須要60/7200≈8.33ms,換句話說,讓磁盤完整的旋轉一圈找到所須要的數據須要8.33ms,這比內存常見的100ns慢100000倍左右,這還不包括移動搖臂的時間。因此在這裏制約查找速度的不是比較次數,而是IO操做的次數。換句話說,若是可以減小一次IO操做,那麼多在內存中比較100次也無所謂,由於兩者的速度相差100000倍。而咱們能夠認爲IO操做的次數就大約等於樹的高度,樹的高度是如何計算的呢?看一下這個公式
咱們想讓這個值儘量的小,就只能讓真數小,或者底數大。真數是數據記錄的條數,不是咱們能決定的。那麼底數呢?這個2來自哪呢?固然是來自二叉樹中的那個二。那麼這個底數能不能變大呢?固然能!!!那就是不要用二叉樹,而要用多叉樹,這就是咱們要說的B樹了。數據庫
B樹也稱B-樹,它是一顆多路平衡查找樹。B樹和後面講到的B+樹都是從最簡單的二叉樹變換而來的。描述一顆B樹時須要指定它的階數,階數表示了一個節點最多有多少個孩子節點,通常用字母m表示階數。下面咱們來看看B樹的定義
(1)樹中每一個節點至多有m 棵子樹(m指的是樹的階);
解釋:有的定義說的是每一個節點最多有m-1個關鍵字,是同樣的,對於每一個節點來講子樹的數目等於關鍵字數目加1,下面會舉例說明。
(2)若根結點不是葉子結點,則至少有兩棵子樹;
解釋:當根節點爲葉子節點時,能夠沒有子樹;不爲葉子節點時,至少有一個關鍵字,也就是至少有兩棵子樹。
(3)除根結點以外的全部非葉子結點至少有⌈m/2⌉個子節點;
解釋:⌈m/2⌉表示向上取整,好比m=5時,⌈m/2⌉=3,表示至少有3個子節點,固然最多有5個。
(4)全部的非葉子結點中包含如下數據:(n,A0,K1,A1,K2,…,Kn,An)
解釋:n爲節點中關鍵字的數目,Ki(i=1,2,…,n)爲關鍵字,且Ki<Ki+1
Ai 爲指向孩子節點的指針(i=0,1,…,n),且指針Ai-1 所指子樹中全部結點的關鍵字均小於Ki (i=1,2,…,n),An 所指子樹中全部結點的關鍵字均大於Kn。(這裏也能夠看到對於每一個節點來講子節點數量比關鍵字數量多1)
(5)全部的葉子結點都出如今同一層次上,即全部葉節點具備相同的深度,等於樹高度。葉子節點除了包含了關鍵字和關鍵字記錄的指針外也有指向其子節點的指針只不過其指針地址都爲null。
下面具體舉個例子說明,相信看了這個例子會對上面的定義有更加深入的理解。
編程
以上圖爲例,假設要查找15的節點,查找流程以下
(1)獲取根節點的關鍵字進行比較,當前根節點關鍵字爲50,50>15,因此找到指向左邊的子節點;
(2)拿到關鍵字10和30,10<15<30 因此直接找到10和30中間的指針指向的子節點;
(3)拿到關鍵字15,就是要查找的目標值, 因此直接返回關鍵字和指針信息(若是樹結構裏面沒有包含所要查找的節點則返回null)
至此咱們便完成了B樹的查找過程,比較簡單,且與二叉查找樹相似。
關於B樹的插入操做,能夠參考【爲何有紅黑樹?什麼是紅黑樹?看完這篇你就明白了】這篇推文中關於2-3樹的插入操做的詳細介紹,其實2-3樹就是一種特殊的B樹。限於篇幅,本文再也不贅述。緩存
B+樹是從B樹衍生而來的,比B樹更具備優越性。B+樹相對於B樹主要作了兩點改進:
(1)非葉結點僅具備索引做用,跟記錄有關的信息均存放在葉結點中。
解釋:B+樹的非葉子節點不保存關鍵字記錄的指針,只進行數據索引;B+樹葉子節點保存了父節點的全部關鍵字記錄的指針,全部數據地址必需要到葉子節點才能獲取到。仍是舉剛纔B樹的例子,B樹中根節點的關鍵字爲50。假如咱們就要查找主鍵爲50的記錄,那麼在B樹中只需進行一次IO操做,將根節點讀入內存,即可以直接命中。而在B+樹中則不一樣,B+樹中任何查詢必需要到葉子節點才能獲取到,因此每次數據查詢的次數都同樣,這一點和B樹有很大區別。
(2)樹的全部葉節點構成一個有序鏈表,能夠按照關鍵字排序的次序遍歷所有記錄。
解釋:這樣作有兩點好處。一是進行範圍查詢更快,數據緊密性很高,緩存的命中率也會比B樹高。二是B+樹全節點遍歷更快,B+樹遍歷整棵樹只須要遍歷全部的葉子節點便可,而不須要像B樹同樣須要對每一層進行遍歷,這有利於數據庫作全表掃描。
推薦閱讀
爲何有紅黑樹?什麼是紅黑樹?看完這篇你就明白了
都2020年了,據說你還不會歸併排序?手把手教你手寫歸併排序算法
爲何會有多線程?什麼是線程安全?如何保證線程安全?安全
以爲文章有用的話,點贊+關注唄,好讓更多的人看到這篇文章,也激勵博主寫出更多的好文章。
更多關於算法、數據結構和計算機基礎知識的內容,歡迎掃碼關注個人原創公衆號「超悅編程」。數據結構