亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁(yè) > 編程 > C > 正文

深入理解C語(yǔ)言B樹原理

2020-02-24 14:38:16
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

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

我們看看它的結(jié)點(diǎn)的結(jié)構(gòu),如下圖所示:


每個(gè)結(jié)點(diǎn)存放著關(guān)鍵字和指向子結(jié)點(diǎn)的指針,很容易看出指針比關(guān)鍵碼多一個(gè)。

由B樹的定義我們可以看出它的一些特點(diǎn):
1.樹高平衡,所有葉結(jié)點(diǎn)在同一層;
2.關(guān)鍵字沒(méi)有重復(fù),按升序排序,父結(jié)點(diǎn)的關(guān)鍵碼是子結(jié)點(diǎn)的分界;
3.B樹把值接近的相關(guān)記錄放在同一磁盤頁(yè)中,從而利用了訪問(wèn)局部性原理;
4.B樹保證一定比例的結(jié)點(diǎn)是滿的,能改進(jìn)空間利用率。

B樹結(jié)點(diǎn)的大小怎么確定呢?為了最小化磁盤操作,通常把結(jié)點(diǎn)大小設(shè)為一個(gè)磁盤頁(yè)的大小。一般樹的高度不會(huì)超過(guò)3層,也就是說(shuō),查找一個(gè)關(guān)鍵碼只需要3次磁盤操作就可以了。
在實(shí)現(xiàn)的時(shí)候,我是參照了《算法導(dǎo)論》的內(nèi)容,先假定:
1.B樹的根結(jié)點(diǎn)始終在主存中,不需要讀磁盤操作;但是,根結(jié)點(diǎn)改變后要進(jìn)行一次寫磁盤操作;
2.任何結(jié)點(diǎn)被當(dāng)做參數(shù)傳遞的時(shí)候,要做一次讀磁盤。

在實(shí)現(xiàn)的時(shí)候其實(shí)還做了簡(jiǎn)化,每個(gè)結(jié)點(diǎn)除了包含關(guān)鍵碼和指針外,還應(yīng)該有該關(guān)鍵碼所對(duì)應(yīng)記錄所在文件的信息的,比如文件偏移量,要不然怎么找到這條記錄呢。在實(shí)現(xiàn)的時(shí)候這個(gè)附加數(shù)據(jù)就沒(méi)有放在結(jié)點(diǎn)里面了,下面是定義樹的結(jié)構(gòu),文件名為btrees.h,內(nèi)容如下:


/* btrees.h */
# define M 2
/* B樹的最小度數(shù)M>=2
* 每個(gè)非根結(jié)點(diǎn)必須至少有M-1個(gè)關(guān)鍵字。每個(gè)非根結(jié)點(diǎn)至少有M個(gè)子女
* 每個(gè)結(jié)點(diǎn)可包含至多2M-1個(gè)關(guān)鍵字。所以一個(gè)內(nèi)結(jié)點(diǎn)至多可以有2M個(gè)子女
*/
typedef int bool ;
struct btnode{ /* B樹結(jié)點(diǎn) */
int keyNum; /* 節(jié)點(diǎn)中鍵的數(shù)目 */
int k[2*M-1]; /* 鍵 */
struct btnode * p[2*M]; /* 指向子樹的指針 */
bool isleaf;
};
struct searchResult{
struct btnode *ptr; /* 數(shù)據(jù)所在節(jié)點(diǎn)指針 */
int pos; /* 數(shù)據(jù)在節(jié)點(diǎn)中位置 */
};

?

下面是創(chuàng)建一顆空樹的代碼,文件名為btree.c:

# include
# include
# include "btrees.h"
/* 給一個(gè)結(jié)點(diǎn)分配空間 */
struct btnode * allocateNode( struct btnode *ptr){
int i,max;
ptr = ( struct btnode *) malloc ( sizeof ( struct btnode));
if (!ptr){
printf ( "allocated error!/n" );
exit (1);
}
max = 2*M;
for (i=0; i ptr->p[i] = NULL; /* 初始化指針 */
memset (ptr->k, 0, (max-1)* sizeof ( int )); /* 初始化鍵的值*/
return ptr;
}
/* 創(chuàng)建一個(gè)空的B樹,就一個(gè)根結(jié)點(diǎn) */
struct btnode * btreeCreate( struct btnode *root){
root = allocateNode(root);
root->keyNum = 0;
root->isleaf = 1;
return root;
}
?
B樹的插入都是在葉子結(jié)點(diǎn)進(jìn)行的,由于B樹的結(jié)點(diǎn)中關(guān)鍵碼的個(gè)數(shù)是有限制的,最小度數(shù)為M的B樹的結(jié)點(diǎn)個(gè)數(shù)是從M-1到2M-1個(gè)。比如下圖是最小度數(shù)為2的B樹(又稱為2-3樹),如下圖所示,它的結(jié)點(diǎn)的個(gè)數(shù)就是1-3個(gè)。

先定位到要插入的位置,如果葉子結(jié)點(diǎn)的關(guān)鍵碼個(gè)數(shù)還沒(méi)達(dá)到上限,比如插入32,就比較簡(jiǎn)單,直接插入就行;如果葉子結(jié)點(diǎn)的關(guān)鍵碼數(shù)到達(dá)了上限,就要分裂成2個(gè)子結(jié)點(diǎn),把中間的關(guān)鍵碼往上放到父節(jié)點(diǎn)中。但有極端的情況,就是父結(jié)點(diǎn)也是滿的,就需要再次分裂,可能最后要把根結(jié)點(diǎn)也分裂了。但是這種算法不太好實(shí)現(xiàn)。
在《算法導(dǎo)論》中實(shí)現(xiàn)用的是另外一種思想,就是先分裂,在查找插入位置的過(guò)程中,如果發(fā)現(xiàn)有滿的結(jié)點(diǎn),就先把它分裂了,這就保證了在最后葉結(jié)點(diǎn)上插入數(shù)據(jù)的時(shí)候,這個(gè)葉結(jié)點(diǎn)的父結(jié)點(diǎn)總是不滿的。下面我們看一個(gè)例子:

我們用逐個(gè)結(jié)點(diǎn)插入的方法創(chuàng)建一棵B樹,結(jié)點(diǎn)順序分別是{18, 31, 12, 10, 15, 48, 45, 47, 50, 52, 23, 30, 20},我們看看具體過(guò)程:
1.創(chuàng)建一個(gè)空的B樹;
2.插入18,這時(shí)候是非滿的,如下所示:


3.同理插入31和12,都比較簡(jiǎn)單,如下所示:


4.插入10,這時(shí)候根結(jié)點(diǎn)是滿的,就要分裂,由于根結(jié)點(diǎn)比較特殊,沒(méi)有父結(jié)點(diǎn),就要單獨(dú)處理,先生成一個(gè)空結(jié)點(diǎn)做為新的根結(jié)點(diǎn),再進(jìn)行分裂,如下所示:


5.再插入15,48,45,由于非滿,直接插入,如下所示:


6.插入47,這次葉結(jié)點(diǎn)滿了,就要先分裂,再插入,如下所示:

其他都是同樣的道理,就不贅述了,下面是源碼,加入到btree.c中,最后寫了個(gè)main函數(shù)和一個(gè)廣度優(yōu)先顯示樹的方法,大家可以自己對(duì)比結(jié)果,代碼的實(shí)現(xiàn)參照了《算法導(dǎo)論》和博客

http://hi.baidu.com/kurt023/blog/item/4c368d8b51c59ed3fc1f10cc.html

他博客里面已經(jīng)實(shí)現(xiàn)了,只是在定義B樹的時(shí)候指針數(shù)和關(guān)鍵碼數(shù)成一樣了,我于是自己重寫了一下。


//函數(shù)目的:分裂存儲(chǔ)數(shù)達(dá)到最大的節(jié)點(diǎn)
void btreeSplitChild( struct btnode *parent, int pos, struct btnode *child){
struct btnode *child2;
int i;
//為新分裂出的節(jié)點(diǎn)分配空間
child2 = allocateNode(child2);
//與被分裂點(diǎn)同級(jí)
child2->isleaf = child->isleaf;
//設(shè)置節(jié)點(diǎn)數(shù)
child2->keyNum = M-1;
//復(fù)制數(shù)據(jù)
for (i=0; i child2->k[i] = child->k[i+M];
//如果不是葉節(jié)點(diǎn),復(fù)制指針
if (!child->isleaf)
for (i=0; i child2->p[i] = child->p[i+M];
child->keyNum = M-1;
//將中間數(shù)作為索引插入到雙親節(jié)點(diǎn)中
//插入點(diǎn)后面的關(guān)鍵字和指針都往后移動(dòng)一個(gè)位置
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;
}
/* 函數(shù)目的:向非滿的節(jié)點(diǎn)中插入一個(gè)數(shù)據(jù)
* 注意:插入前保證key在原來(lái)的B樹中不存在
*/
void btreeInsertNoneFull( struct btnode *ptr, int data){
int i;
struct btnode *child; //要插入結(jié)點(diǎn)的子結(jié)點(diǎn)
i = ptr->keyNum;
//如果是葉節(jié)點(diǎn),直接插入數(shù)據(jù)
if (ptr->isleaf){
while ((i>0) && (datak[i-1])){
ptr->k[i] = ptr->k[i-1];
i--;
}
//插入數(shù)據(jù)
ptr->k[i] = data;
ptr->keyNum++;
}
else { //不是葉節(jié)點(diǎn),找到數(shù)據(jù)應(yīng)插入的子節(jié)點(diǎn)并插入
while ((i>0) && (datak[i-1]))
i--;
child = ptr->p[i];
if (child->keyNum == 2*M-1){
btreeSplitChild(ptr, i, child);
if (data > ptr->k[i])
i++;
}
child = ptr->p[i];
btreeInsertNoneFull(child, data); //在子樹中遞歸
}
}
/* 插入一個(gè)結(jié)點(diǎn) */
struct btnode * btreeInsert( struct btnode *root, int data){
struct btnode * new ;
/* 檢查是否根節(jié)點(diǎn)已滿,如果已滿,分裂并生成新的根節(jié)點(diǎn) */
if (root->keyNum == 2*M-1){
new = allocateNode( new );
new ->isleaf = 0;
new ->keyNum = 0;
new ->p[0] = root;
btreeSplitChild( new , 0, root);
btreeInsertNoneFull( new , data);
return new ;
}
else { //還沒(méi)到最大數(shù)據(jù)數(shù),直接插入
btreeInsertNoneFull(root, data);
return root;
}
}
//函數(shù)目的:廣度優(yōu)先顯示樹
void btreeDisplay( struct btnode *root){
int i, queueNum=0;
int j;
struct btnode *queue[20];
struct btnode *current;
//加入隊(duì)列
queue[queueNum] = root;
queueNum++;
while (queueNum>0){
//出隊(duì)
current = queue[0];
queueNum--;
//移出第一個(gè)元素后后面的元素往前移動(dòng)一個(gè)位置
for (i=0; i queue[i] = queue[i+1];
//顯示節(jié)點(diǎn)
j = current->keyNum;
printf ( "[ " );
for (i=0; i printf ( "%d " , current->k[i]);
}
printf ( "] " );
//子節(jié)點(diǎn)入隊(duì)
if (current!=NULL && current->isleaf!=1){
for (i=0; ikeyNum); i++){
queue[queueNum] = current->p[i];
queueNum++;
}
}
}
printf ( "/n" );
}
int main()
{
struct btnode *root;
int a[13] = {18, 31, 12, 10, 15, 48, 45, 47, 50, 52, 23, 30, 20};
int i;
root = btreeCreate(root);
for (i=0; i root = btreeInsert(root, a[i]);
btreeDisplay(root);
}
return 0;
}

?

?

?

?

運(yùn)行結(jié)果:

同樣一批關(guān)鍵碼用不同算法生成的B樹可能是不同的,比如4個(gè)關(guān)鍵碼的結(jié)點(diǎn)[1,2,3,4]分裂的時(shí)候,把2或3放上去都可以;同樣的算法插入順序不同也可能不同。
附件中是源碼,在Linux下編譯通過(guò)。

以上就是深入理解C語(yǔ)言B樹原理的全部?jī)?nèi)容,感謝大家的閱讀,更多內(nèi)容請(qǐng)關(guān)注武林技術(shù)頻道網(wǎng)站。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表

圖片精選

youjizzxxxx18| av电影资源| 久久久久久久午夜| 欧美日韩系列| 在线免费观看av网站| 亚洲日本伦理| 欧美影院在线| 天天干天天操天天做| 日韩精品 欧美| 欧美一级淫片aaaaaa| av男人一区| 国产精选第一页| 久色视频在线| 99久免费精品视频在线观看| 九九九久久久精品| 午夜一级免费视频| av在线三区| 人人影院免费大片| 欧美日韩免费看片| 神马久久久久久久久久久| 午夜精品成人av| xxxx欧美xxxx黑人| 久久99精品国产| 国产二级c片l毛片| 国产区成人精品视频| 人妻无码一区二区三区| 可以免费看av的网址| 精品91自产拍在线观看一区| 九九热线视频只有这里最精品| 国产原创一区二区| 99国产精品久久久久| 先锋影音在线资源站91| 雨宫琴音一区二区在线| 日本高清xxxx| 日本免费资源| 国产裸体无遮挡| 91麻豆精品国产91| 9色在线视频| 精品国产视频一区二区三区| 欧美精品一区二区三区蜜桃| 日韩三级中文字幕| 久久xxx视频| 国产高清在线免费观看| 日韩人妻精品中文字幕| 久久91亚洲人成电影网站| 国产又粗又黄又爽的视频| 91嫩草|国产丨精品入口| 国产精品嫩草影院在线看| 女人喷潮完整视频| 一级片免费观看视频| 国产一区二区影视| 在线精品播放av| 亚洲mv大片欧洲mv大片精品| 成人av免费电影| 亚洲看片免费| 国内精品不卡| 日韩经典中文字幕在线观看| 99久久国产综合精品色伊| 成人激情综合| 日韩男人的天堂| 西野翔中文久久精品字幕| 欧美色图免费看| 日韩日韩日韩日韩| 青青草一区二区三区| 国产经典第一页| 免费a在线观看| 日韩激情第一页| 日本一二三四区视频| 97caopor国产在线视频| 精品国产乱码久久久久久1区二区| 亚洲综合精品自拍| 亚洲18私人小影院| 日韩av中文在线观看| av高清日电影| 岛国电影中文在线| 一区二区三区高清| 国产精品三级av在线播放| 欧美一级高清免费播放| 翡翠波斯猫1977年美国| 国产精品网站导航| 久久久久黄久久免费漫画| 久久艹精品视频| 国产精品美女久久久浪潮软件| 风流少妇一区二区| 成人在线视频电影| 久久久久久久久影院| 91精品国产一区二区在线观看| 欧美激情第一区| 日韩欧美一区中文| 欧美放荡办公室videos4k| 亚洲资源在线看| 日韩在线视频观看免费| 福利电影一区二区| 欧美一级片久久久久久久| 国产区美女在线| 国产一区二区三区四区在线| 日韩免费av一区二区| 美女视频在线免费| 欧美影片第一页| 精品人妻一区二区三区日产乱码| 18成人免费观看网站下载| 美女网站视频在线| 在线视频精品一| 99在线热播精品免费99热| www五月婷婷| 国产sm在线观看| 国内精品久久99人妻无码| 亚洲综合日韩欧美| 精品夜夜嗨av一区二区三区| 国产精品videossex久久发布| 青青草av网站| 亚洲欧美另类自拍| 国产精品19p| 高清免费观看在线| 久久丁香综合五月国产三级网站| 逼特逼视频在线观看| 亚洲一区二区伦理| 给我看免费高清在线观看| ...中文天堂在线一区| 欧美顶级少妇做爰| 男人日女人下面视频| 色av中文字幕一区| 亚洲精品日韩在线观看| 国产无套内射久久久国产| 欧美裸体男粗大视频在线观看| 久久精品凹凸全集| 亚洲高清影视| 夜夜嗨av色综合久久久综合网| 男裸体无遮挡网站| 日韩一级免费观看| 日本成人在线免费观看| 头脑特工队2在线播放| 欧洲国产精品| 2021国产精品久久精品| 最近2019好看的中文字幕免费| 91精品婷婷国产综合久久| 色噜噜国产精品视频一区二区| 国产a级毛片一区| 国产美女视频一区二区三区| 欧美精品人人做人人爱视频| 亚洲国产精品一区二区久| bbw丰满大肥奶肥婆| 91精品视频免费在线观看| 成人网站免费观看入口| 欧美性做爰猛烈叫床潮| 亚洲精品久久久蜜桃动漫| 成熟老妇女视频| 99久久夜色精品国产网站| 一级黄色特级片| 久久久国产精品一区二区中文| 男人女人黄一级| 最新二区三区av| sm性调教片在线观看| 国产一区二区三区在线观看网站| 51ⅴ精品国产91久久久久久| 公肉吊粗大爽色翁浪妇视频| 在线免费观看欧美| 久草一区二区| 欧美一区二区视频17c| 亚洲欧美国产日韩天堂区| 亚洲精品蜜桃久久久久久| 另类尿喷潮videofree| 久久九九国产视频| 91福利视频在线观看| 国产美女精彩久久| 亚洲天堂网中文字| 欧美乱强性伦xxxxx| 91在线资源| 国产一区不卡视频| 91中文字幕精品永久在线| 黄色一级片在线看| 男人插女人下面免费视频| 欧美人禽zoz0强交| 高清视频一区| 日韩一级欧美一级| 国产成人激情av| 欧美一级欧美一级| 亚洲欧美日韩综合国产aⅴ| 一个人看的日本www的免费视频| 国产黄色av片| 亚洲系列中文字幕| 精品免费视频123区| 久久av红桃一区二区禁漫| 欧美熟女一区二区| 国产馆在线观看| 欧美影视一区在线| 一区二区亚洲精品| 久久影院一区二区三区| 亚洲热av色在线播放| 天天天干夜夜夜操| 亚洲制服中文| 美女免费视频网站| 刘亦菲一区二区三区免费看| 久久国产高清视频| 日本免费看片网站| 国产精品电影久久久久电影网| 日本成人看片网址| 欧美 丝袜 自拍 制服 另类| 欧美日韩视频专区在线播放| 久久精品国产亚洲夜色av网站| 日本久久一区| 在线视频观看你懂的| 一卡二卡在线观看| 国产精品激情av电影在线观看| 日韩成人视屏| 国内精品久久影院| www.aqdy爱情电影网| 国产免费一区二区三区最新6| 日韩在线电影一区| 欧美亚洲成人网| 日韩欧美激情一区| 欧美性xxxx极品hd欧美风情| 国产suv一区二区三区88区| 中文av在线全新| 亚洲欧美在线x视频| 国产精品入口麻豆高清| 精品176二区| 欧美日韩三级在线观看| 91精品久久香蕉国产线看观看| 国产经典自拍视频在线观看| 日韩av资源| 夜夜添无码一区二区三区| 伊人亚洲福利一区二区三区| 久久精品国产亚洲AV成人婷婷| 日本精品免费观看高清观看| 国内精品模特av私拍在线观看| 日韩欧美高清在线观看| 91在线|亚洲| 久久精品国内一区二区三区| 免费一级肉体全黄毛片| 久久久久久无码精品大片| 99精品国产福利在线观看免费| 91ts人妖另类精品系列| 三区四区在线观看| 亚洲不卡av一区二区三区| 成人av片在线观看| 精品国产影院| 欧美精品电影| h片视频在线观看| 久久精品夜夜夜夜夜久久| 欧美久久在线观看| 久久影院资源站| 盗摄女厕thunder| 超碰成人在线观看| 欧洲视频一区| 91在线视频免费观看| huan性巨大欧美| 日韩综合第一页| 久久精品国产久精国产爱| 五月天国产在线| 中文字幕乱码人妻综合二区三区| 92久久精品一区二区| 三区四区在线视频| 久久精品国产99国产精品澳门| 国产精品丝袜高跟| 国产精品女主播一区二区三区| 99精品美女视频在线观看热舞| 男人天堂综合| 你真棒插曲来救救我在线观看| 国产欧美在线观看免费| 国产精品国产三级国产传播| 国产精品你懂的在线观看| 三级三级久久三级久久18| 五月激情综合色| 综合久久久久综合| 日韩精品中文字幕一区| 成人网ww555视频免费看| 欧美日韩黄色一区二区| 一区二区三区我不卡| 久久久久久久免费| 99在线精品一区二区三区| 中文亚洲欧美| 污网站免费在线| 欧美午夜不卡影院在线观看完整版免费| 先锋影音av网站| 精品国产乱码久久久久久夜甘婷婷| 亚洲视频综合网| 成人免费淫片95视频观看网站| 欧美在线亚洲综合一区| 久久精品国内一区二区三区水蜜桃| 亚洲成人免费在线视频| 懂色av中文一区二区三区天美| 97久久精品一区二区三区的观看方式| 婷婷激情五月综合| 国产一卡2卡3卡四卡网站| 欧美一区视频在线| 一本到不卡免费一区二区| 波多野结衣视频在线播放| 久久久噜噜噜久久人人看| 51蜜桃传媒精品一区二区| 日精品一区二区| 国产精品99一区二区三区| 日韩激情美女| 嫩草成人www欧美| 韩国av一区二区| 日韩欧美性视频| 日韩欧美一区二区三区四区| 丝袜人妻一区二区三区| 成人性生交大片免费观看网站| 久久成人福利视频| 日韩三级高清在线| 日中文字幕在线| 一菊综合网成人综合网| 国产精品午夜久久| 亚洲一区二区视频在线| 91网站最新网址| 中文字幕久久熟女蜜桃| 国产美女无遮挡永久免费| 涩涩屋成人免费视频软件| 中文字字幕在线中文乱码电影| 国产一级二级av| aaaaa一级片| 婷婷在线视频观看| 一区二区三区在线视频观看| 精品毛片在线观看| 麻豆国产入口在线观看免费| 久久精品国产色蜜蜜麻豆| 欧美日韩激情在线一区二区三区| 在线视频你懂得一区二区三区| 亚洲aa中文字幕| 国产精品日韩无码| 成年人视频在线免费| 成人精品一区二区三区电影免费| 日韩av影院| 国内不卡一区二区三区| 久久久久网站| 日韩色av导航| 欧美日本另类xxx乱大交|