二叉樹、平衡二叉樹、B-Tree與B+Tree


本文總結自:https://blog.csdn.net/chuixue24/article/details/80027689

二叉樹(B樹,binary tree)

左子樹的鍵值 < 根的鍵值 < 右子樹的鍵值

該二叉樹的節點進行查找深度為1的節點的查找次數為1,深度為2的查找次數為2,深度為n的節點的查找次數為n

若想二叉樹的查詢效率盡可能高,需要這棵二叉樹是平衡的,從而引出新的定義——平衡二叉樹,或稱AVL樹。

 

平衡二叉樹(AVL樹,Adelson-Velskii and Landis tree)

任何節點的兩個子樹的高度最大差為1

備注:高度:從其最低后代節點往上數的節點個數

 

平衡多路二叉樹(B- 樹/B_樹/B樹,balance- tree)

多路:即節點不再是兩個子節點,可以有多個

B-Tree是為磁盤等外存儲設備設計的一種平衡查找樹

系統從磁盤讀取數據到內存時是以磁盤塊(block)為基本單位的,位於同一個磁盤塊中的數據會被一次性讀取出來,而不是需要什么取什么。

而InnoDB存儲引擎中有頁(Page)的概念,頁是其磁盤管理的最小單位。InnoDB存儲引擎中默認每個頁的大小為16KB,可通過參數innodb_page_size將頁的大小設置為4K、8K、16K。

而一個磁盤塊的存儲空間往往沒有這么大,因此InnoDB每次申請磁盤空間時都會是若干地址連續磁盤塊來達到頁的大小16KB。

InnoDB在把磁盤數據讀入到磁盤時會以頁為基本單位,在查詢數據時,如果一個頁中的每條數據都能有助於定位數據記錄的具體位置,那么將會減少磁盤I/O次數,提高查詢效率。

B-Tree結構的數據可以讓系統高效的找到數據所在的磁盤塊。

 

以下為每頁的結構: 

每個節點占用一個盤塊的磁盤空間,一個節點上有兩個升序排序的關鍵字和三個指向子樹根節點的指針,指針存儲的是子節點所在磁盤塊的地址。

兩個關鍵詞划分成的三個范圍域對應三個指針指向的子樹的數據的范圍域。以根節點為例:關鍵字為17和35,P1指針指向的子樹的數據范圍為小於17,P2指針指向的子樹的數據范圍為17~35,P3指針指向的子樹的數據范圍為大於35。

模擬查找關鍵字29的過程:

  1. 根據根節點找到磁盤塊1,讀入內存。【磁盤I/O操作第1次】
  2. 比較關鍵字29在區間(17,35),找到磁盤塊1的指針P2。
  3. 根據P2指針找到磁盤塊3,讀入內存。【磁盤I/O操作第2次】
  4. 比較關鍵字29在區間(26,30),找到磁盤塊3的指針P2。
  5. 根據P2指針找到磁盤塊8,讀入內存。【磁盤I/O操作第3次】
  6. 在磁盤塊8中的關鍵字列表中找到關鍵字29。

分析上面過程,發現需要3次磁盤I/O操作,和3次內存查找操作。由於內存中的關鍵字是一個有序表結構,可以利用二分法查找提高效率。而3次磁盤I/O操作是影響整個B-Tree查找效率的決定因素。B-Tree相對於AVLTree縮減了節點個數,使每次磁盤I/O取到內存的數據都發揮了作用,從而提高了查詢效率。

 

B+Tree(balance+ tree)

B+Tree是在B-Tree基礎上的一種優化,使其更適合實現外存儲索引結構,InnoDB存儲引擎就是用B+Tree實現其索引結構。

B-Tree結構圖中可以看到每個節點中不僅包含數據的key值,還有data值(非葉子節點也有)。而每一個頁的存儲空間是有限的,

如果data數據較大時將會導致每個節點(即一個頁)能存儲的key的數量很小

當存儲的數據量很大時同樣會導致B-Tree的深度較大,增大查詢時的磁盤I/O次數,進而影響查詢效率。

在B+Tree中,所有數據記錄節點都是按照鍵值大小順序存放在同一層的葉子節點上,而非葉子節點上只存儲key值信息,這樣可以大大加大每個節點存儲的key值數量,降低B+Tree的高度。

且B+樹的所有關鍵字的具體信息都存儲在葉子結點,通常都會使用鏈表將葉子結點連接起來,遍歷葉子結點就能夠獲取到所有的數據,也就可以進行區間查詢,而B樹只有中序遍歷才能夠獲取到所有的數據。

1. 提高深度,提高存儲量

2. 適合區間查詢

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM