B樹簡單理解

平衡二叉排序樹便於動態查找,因此用平衡二叉排序樹來組織索引表是一種可行的選擇。當用於大型數據庫時,所有數據及索引都存儲在外存,因此,涉及到內、外存之間頻繁的數據交換,這種交換速度的快慢成爲制約動態查找的瓶頸。若以二叉樹的結點作爲內、外存之間數據交換單位,則查找給定關鍵字時對磁盤平均進行㏒㏒次訪問是不能容忍的樹的深度過大而造成磁盤I/O讀寫過於頻繁,進而導致查詢效率低下)。

磁盤讀取數據是以盤塊(block)爲基本單位的。位於同一盤塊中的所有數據都能被一次性全部讀取出來。而磁盤IO代價主要花費在查找時間Ts上。因此我們應該儘量將相關信息存放在同一盤塊,同一磁道中。或者至少放在同一柱面或相鄰柱面上,以求在讀/寫信息時儘量減少磁頭來回移動的次數,避免過多的查找時間Ts

所以,在大規模數據存儲方面,大量數據存儲在外存磁盤中,而在外存磁盤中讀取/寫入塊(block)中某數據時,首先需要定位到磁盤中的某塊,如何有效地查找磁盤中的數據,需要一種合理高效的外存數據結構,就是下面所要重點闡述的B-tree結構,以及相關的變種結構:B+-tree結構和B*-tree結構。


因此,必須選擇一種能儘可能降低磁盤I/OI/O次數的索引組織方式。樹結點的大小儘可能地接近頁的大小。
     B樹主要用於文件系統中,在B樹中,每個節點的大小爲一個磁盤的頁,節點中鎖包含的關鍵字及其子節點的數目取決於頁的大小。一個度爲m的B樹,稱爲m階B樹,定義如下:
     (1)一個m階B樹,或者是空樹,或者滿足一下性質的m叉樹;
     (2)根節點或者是葉子,或者至少有兩顆子樹,至多是m棵子樹;
     (3)除根節點外,所有非終端節點至少是「m/2 (向上取整)棵子樹,至多是m棵子樹;
     (4)所有葉子節點都在樹的同一層上。
     (5)


     下圖爲B樹的一個例子:
     


1,B樹的數據結構,根據以上的信息,定義B樹的數據結構如下:
//節點數據結構的定義
typedef struct BTNode
{
    int keynum;             //節點信息的數量,不包含key[0]節點
    struct BTNode *parent;  //父節點
    int key[M+1];           //節點信息數組,第一個節點沒用。
    struct BTNode *ptr[M+1];//子節點信息        
}BTNode;

2,B樹的查找
     查找的基本思想是:
     (1)從樹的根節點T開始,在節點中利用遍歷或折半查找給定的值,如果找到,則返回節點指針和在節點中的位置;如果沒有,則到(2)
     (2)與節點中的Key進行比較,找到給定值左右Key中間的指針,去其子樹中查找
     (3)重複執行1,2兩步,直到找到。如果直到葉子節點,仍未找到,則返回0,並返回最後搜索的葉子節點。(此節點是給定值需要插入的位置)

3,B樹的插入
     插入新節點的基本思想如下:
     (1)在B樹查找關鍵字,如果找到,則不插入;否則,執行(2)
     (2)將給定值插入到葉子節點中,如果:
          a,葉子的節點數
          b,葉子的節點數=m-1:插入節點,並將節點分裂。分裂的方式是將該節點拆分成兩個節點,然後,將中間節點插入到父節點當中,拆分後的兩個節點,分別作爲插入到父節點的中間節點的左右子。如果中間節點插入到父節點後,仍然需要分裂,則繼續分裂,直到根節點。如果仍然需要分裂,則新建一個根節點,將分裂後的兩個節點分別作爲新根節點的兩個子節點。
     例如如下圖:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章