面試官:你知道文件索引、數據庫索引通常用什麼數據結構來存儲嗎?面試
小秋:知道啊,通常都是用樹形結構來存儲的。算法
面試官:能夠說說爲啥用樹形結構來存儲嗎?數據庫
小秋:樹形結構例如想 B 樹,B+ 樹,二叉查找樹都是有序的,因此查詢效率很高,能夠再 O(logn) 的時間複雜度查找到目標數據。微信
面試官:那能夠問問文件索引,例如數據庫索引通常用哪一種樹形結構嗎?數據結構
小秋:大部分用 B+ 樹,少部分用 B 樹。(B和B+樹太他麼複雜了,幸虧背了下面試題,嘻嘻)工具
面試官:想問下爲什呀要用 B 樹而不用二叉查找樹啊?或者爲啥不用哈希表啊?哈希表的查找速度也很快呀。開發工具
小秋:哈希表雖然可以再 O(1) 查找到目標數據,不過若是咱們要進行模糊查找的話,卻只能遍歷全部數據,而且若是出現了極端狀況,哈希表衝突的元素太多,也會致使線性時間的查找效率的。3d
面試官:那爲啥不用二叉查找樹呢?cdn
小秋:這個…..其實我也不知道,當時是再某個面試題中看到的答案的,嘻嘻。視頻
面試官:那你能夠回去等通知了….
小秋被懟後有點沮喪,跑過來問帥地關於 B 樹的一些知識以及心中的疑問。
小秋:今天去面試,面試問我,爲啥文件索引要用 B 樹而不用二叉查找樹,而後我想了下,感受若是這是一顆比較平衡的二叉查找樹的話,那麼查找效率是很是快的,難度 B 樹還能比它更快嗎?
帥地:確實,若是是查找效率(即比較次數)的話,實際上二叉樹能夠說是最快的了,可是,咱們的文件索引是存放在磁盤上的,因此咱們不只要考慮查找效率,還要考慮磁盤的尋址加載次數哦,而這也是咱們爲何要用 B 樹的緣由。
小秋:難道二叉查找樹會致使磁盤的加載次數更多嗎?能夠給我詳細講講嗎?
帥地:能夠呀,不過聽懂了,以爲我講的不錯,你要記得給我多點贊,轉發哦。
小秋:絕對沒問題。
帥地:要講懂這個問題,咱們先來了解一下什麼是 B 樹,其實,B 樹和二叉查找樹同樣,都是樹,B 樹至關因而一棵多叉查找樹,對於一棵 m 階的 B 樹具備以下特性:
一、根節點至少有兩個孩子。
二、每一箇中間節點都包含 k - 1 個元素和 k 個孩子,其中 m/2 <= k <= m。
三、每個葉子節點都包含 k - 1 個元素,其中 m/2 <= k <= m。
四、全部的葉子節點都位於同一側。
五、每一個節點中的元素從小到大排列,節點當中的 k - 1 個元素正好是 k 個孩子包含的元素的值域劃分。
小秋:我去,這麼複雜,鬼才記得住,我仍是選擇不學了,嗚嗚。
帥地:你彆着急,這些規則我也記不住,只是讓你大體知道一些這些規則,通常狀況下,咱們並不須要把它的規則徹底背起來滴。爲了加深理解,我給你舉個 B 樹的例子吧。例如:
圖中是一棵m = 3 的 3 階 B 樹,能夠看出,樹中有些節點是有多個元素的,而且和二叉查找樹同樣,左節點的全部元素的值都比父親元素小。例如對於(3, 7)這個節點。兩個元素把這個節點分割成三個值域,便可以有 3 個孩子。2 至關於 3 的左孩子節點,而 (4,6)至關於 3 的右孩子,同時也是 7 的左孩子,而 9 是 7 的右孩子。
和二叉查找樹仍是很類似滴,都是有序,且左孩子小,右孩子大,只是 B 樹的一個節點能夠有多個元素,而且有多個分支。而這些分支以及元素的數量規則,能夠從上面的五個規則中查找哈。說實話,我也懶的記那些規則,只知道個大概以及 B 樹的應用便可。
文章來源於微信公衆:『苦逼的碼農』,更多文章可搜索關注
小秋:我知道了,不過這種多叉的樹,真的能夠比二叉查找樹效率更好嗎,我怎麼以爲不能夠呢?
帥地:那你能夠說說哦。
小秋:例如,上面的 B 樹有 11 個元素,按照這 11 個元素,咱們創建一個以下的二叉查找樹,如圖(我去,這個圖話了好長時間,ppt 畫的)
下面咱們來進行查詢效率比較
一、在 B 樹中的查找次數。 如今假如咱們要查詢元素 9,對於 B 樹,咱們須要進行4次比較,例如: 第一次比較: 10 比較,比 10 小,因此再 10 的左孩子找。
第2、三次比較:和 3 比較,比 3 大,這個時候咱們還得和 7 比較。
第四次比較:和 9 比較,相等,找到目標樹,返回。
因此最終的結果須要 4 次比較。
二、在二叉樹的比較結果
爲了節省篇幅,我就不逐個比較了,相信你也一眼就看出來了,也是須要 4 次比較。如圖
小秋:一樣都是四次比較,並且,B 樹的每個節點,若是存放的元素比較多,那麼 B 樹的比較次數會更多,爲何就說 B 的效率比 二叉查找樹快呢?
帥地:確實,若是單單從比較次數看的話,二叉查找樹確實不比 B 樹差,不過你忽略了一個很重要的點,那就是磁盤的尋址加載次數。
咱們知道,在把磁盤裏的數據加載到內存中的時候,是以頁爲單位來加載的,而咱們也知道,節點與節點之間的數據是不連續的,因此不一樣的節點,頗有可能分佈在不一樣的磁盤頁中。因此對於上面的二叉查找樹,咱們可能須要進行 4 次尋址加載,如圖:
而對於 B 樹,因爲 B 樹的每個節點,能夠存放多個元素,因此磁盤尋址加載的次數會比較少,例如上面的例子中,用 B 樹的話,只須要加載 3 次,如圖:
咱們都知道,在內存的運算速度是很是快的,至少比磁盤的尋址加載速度,快了幾百倍,而咱們進行數值比較的時候,是在內存中進行的,雖然 B 樹的比較次數可能比二叉查找樹多,可是磁盤操做次數少,因此整體來講,仍是 B 樹快的多,這也是爲何咱們用使用 B 樹來存儲的緣由。
小秋:原來這樣啊,之前一直矇在鼓裏。
文章來源於微信公衆:『苦逼的碼農』,更多文章可搜索關注
帥地:不知道你發現沒有,實際上磁盤的加載次數,基本上是和樹的高度相關聯的,高度越高,加載次數越多,越矮,加載次數越少。因此對於這種文件索引的存儲,咱們通常會選擇矮胖的樹形結構。例若有 1000 個元素,若是是二叉查找樹的話,高度可能高達 10 層,而若是用 10 階 B 樹的話,只須要三四層便可。
小秋:終於搞懂了,不過我還有個疑問,大部分文件索引或者數據庫索引都是用 B+ 樹的,而只有小部分才用 B 樹,能夠問下爲什要用 B+ 樹而不用 B 樹嗎?還有,B 樹還有其餘的應用嗎?
帥地:B 樹處於會用在少部分的文件索引(數據庫索引)外,應用的最多的就是文件系統了。至於爲什呀要用 B 樹而不用 B+ 樹,爲何數據庫索引大部分用 B+ 樹而不用 B 樹,咱們下節再講了。
小秋:那我期待着。
帥地:若是以爲有收穫,能夠幫忙多多轉發,點贊,分享哦,這也是我寫文章的動力來源。
關於 B 樹和 B+ 樹,在面試的過程當中,仍是問的挺多滴,特別是問到數據庫的時候,基本會問索引,進而問到 B+ 樹,從而也會扯到 B 樹。因此掌握着兩種樹的應用以及原理,是很是重要的,雖然他們的規則很複雜,可是若是是應付面試等,其實不須要背那些規則,只須要知道大概以及知道他們的原理便可。
若是你以爲這篇內容對你挺有啓發,我想邀請你幫我三個忙,讓更多的人看到這篇文章:
一、點贊,讓更多的人也能看到這篇內容(收藏不點贊,都是耍流氓 -_-)
二、關注我和專欄,讓咱們成爲長期關係
三、關注公衆號「苦逼的碼農」,主要寫算法、計算機基礎之類的文章,裏面已有100多篇原創文章