c語言B樹深入理解
B樹是為磁盤或其他直接存儲設備設計的一種平衡查找樹。如下圖所示。每一個結點箭頭指向的我們稱為入度,指出去的稱為出度。樹結構的結點入度都是1,不然就變成圖了,所以我們一般說樹的度就是指樹結點的出度,也就是一個結點的子結點個數(shù)。有了度的概念我們就簡單定義一下B樹(假設一棵樹的最小度數(shù)為M):
1.每個結點至少有M-1個關鍵碼,至多有2M-1個關鍵碼;
2.除根結點和葉子結點外,每個結點至少有M個子結點,至多有2M個子結點;
3.根結點至少有2個子結點,唯一例外是只有根結點的情況,此時沒有子結點;
4.所有葉子結點在同一層。

我們看看它的結點的結構,如下圖所示:

每個結點存放著關鍵字和指向子結點的指針,很容易看出指針比關鍵碼多一個。
由B樹的定義我們可以看出它的一些特點:
1.樹高平衡,所有葉結點在同一層;
2.關鍵字沒有重復,按升序排序,父結點的關鍵碼是子結點的分界;
3.B樹把值接近的相關記錄放在同一磁盤頁中,從而利用了訪問局部性原理;
4.B樹保證一定比例的結點是滿的,能改進空間利用率。
B樹結點的大小怎么確定呢?為了最小化磁盤操作,通常把結點大小設為一個磁盤頁的大小。一般樹的高度不會超過3層,也就是說,查找一個關鍵碼只需要3次磁盤操作就可以了。
在實現(xiàn)的時候,我是參照了《算法導論》的內容,先假定:
1.B樹的根結點始終在主存中,不需要讀磁盤操作;但是,根結點改變后要進行一次寫磁盤操作;
2.任何結點被當做參數(shù)傳遞的時候,要讀磁盤。
在實現(xiàn)的時候其實還做了簡化,每個結點除了包含關鍵碼和指針外,還應該有該關鍵碼所對應記錄所在文件的信息的,比如文件偏移量,要不然怎么找到這條記錄呢。在實現(xiàn)的時候這個附加數(shù)據(jù)就沒有放在結點里面了,下面是定義樹的結構,文件名為btrees.h,內容如下:
/* btrees.h */
# define M 2
/* B樹的最小度數(shù)M>=2
* 每個非根結點必須至少有M-1個關鍵字。每個非根結點至少有M個子女
* 每個結點可包含至多2M-1個關鍵字。所以一個內結點至多可以有2M個子女
*/
typedef int bool ;
struct btnode{ /* B樹結點 */
int keyNum; /* 節(jié)點中鍵的數(shù)目 */
int k[2*M-1]; /* 鍵 */
struct btnode * p[2*M]; /* 指向子樹的指針 */
bool isleaf;
};
struct searchResult{
struct btnode *ptr; /* 數(shù)據(jù)所在節(jié)點指針 */
int pos; /* 數(shù)據(jù)在節(jié)點中位置 */
};
他博客里面已經(jīng)實現(xiàn)了,只是在定義B樹的時候指針數(shù)和關鍵碼數(shù)成一樣了,我于是自己重寫了一下。
[code]
void btreeSplitChild( struct btnode *parent, int pos, struct btnode *child){
struct btnode *child2;
int i;
child2 = allocateNode(child2);
child2->isleaf = child->isleaf;
//設置節(jié)點數(shù)
child2->keyNum = M-1;
//復制數(shù)據(jù)
for (i=0; i<M-1; i++)
child2->k[i] = child->k[i+M];
//如果不是葉節(jié)點,復制指針
if (!child->isleaf)
for (i=0; i<M; i++)
child2->p[i] = child->p[i+M];
child->keyNum = M-1;
for (i=parent->keyNum; i>pos; i--){
parent->k[i] = parent->k[i-1];
parent->p[i+1] = parent->p[i];
}
parent->k[pos] = child->k[M-1];
parent->keyNum++;
parent->p[pos+1] = child2;
}
相關文章
Matlab實現(xiàn)讀寫txt文件數(shù)據(jù)與進制轉換
這篇文章主要為大家詳細介紹了Matlab實現(xiàn)讀寫txt文件數(shù)據(jù)與進制轉換的相關知識,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2023-12-12
C++的靜態(tài)成員變量和靜態(tài)成員函數(shù)你了解多少
這篇文章主要為大家詳細介紹了C++的靜態(tài)成員變量和靜態(tài)成員函數(shù),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02

