一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

SQLite B+樹實現(xiàn)代碼

 king9413 2010-03-30

這個結(jié)構(gòu)一般用于數(shù)據(jù)庫的索引,綜合效率非常高,像 Berkerly DB , sqlite , mysql 數(shù)據(jù)庫都使用了這個算法處理索引。
如果想自己做個小型數(shù)據(jù)庫,可能參考一下這個算法的實現(xiàn),可能會對你有所幫助。

其中的注冊很詳細,不用再多說了。

/* btrees.h */ 
/* 
* 平衡多路樹的一種重要方案。 
* 在 1970 年由 R. Bayer 和 E. McCreight 發(fā)明。 
*/ 
#define M 1 
/* B 樹的階,即非根節(jié)點中鍵的最小數(shù)目。 
* 有些人把階定義為非根節(jié)點中子樹的最大數(shù)目。 
*/ 
typedef 
int typekey; 
typedef 
struct btnode { /* B-Tree 節(jié)點 */ 
int d; /* 節(jié)點中鍵的數(shù)目 */ 
typekey k[
2*M]; /* 鍵 */ 
char *v[2*M]; /* 值 */ 
struct btnode *p[2*M+1]; /* 指向子樹的指針 */ 
} node, 
*btree; 
/* 
* 每個鍵的左子樹中的所有的鍵都小于這個鍵, 
* 每個鍵的右子樹中的所有的鍵都大于等于這個鍵。 
* 葉子節(jié)點中的每個鍵都沒有子樹。 
*/ 

/* 當 M 等于 1 時也稱為 2-3 樹 
* +----+----+ 
* | k0 | k1 | 
* +-+----+----+--- 
* | p0 | p1 | p2 | 
* +----+----+----+ 
*/ 
extern int btree_disp; /* 查找時找到的鍵在節(jié)點中的位置 */ 
extern char * InsValue; /* 與要插的鍵相對應(yīng)的值 */ 

extern btree search(typekey, btree); 
extern btree insert(typekey,btree); 
extern btree delete(typekey,btree); 
extern int height(btree); 
extern int count(btree); 
extern double payload(btree); 
extern btree deltree(btree); 
/* end of btrees.h */ 

/*******************************************************/ 

 

/*******************************************************/ 

/* btrees.c */ 
#include 
#include 
#include 
"btrees.h" 

btree search(typekey, btree); 
btree insert(typekey,btree); 
btree delete(typekey,btree); 
int height(btree); 
int count(btree); 
double payload(btree); 
btree deltree(btree); 

static void InternalInsert(typekey, btree); 
static void InsInNode(btree, int); 
static void SplitNode(btree, int); 
static btree NewRoot(btree); 

static void InternalDelete(typekey, btree); 
static void JoinNode(btree, int); 
static void MoveLeftNode(btree t, int); 
static void MoveRightNode(btree t, int); 
static void DelFromNode(btree t, int); 
static btree FreeRoot(btree); 

static btree delall(btree); 
static void Error(int,typekey); 

int btree_disp; /* 查找時找到的鍵在節(jié)點中的位置 */ 
char * InsValue = NULL; /* 與要插的鍵相對應(yīng)的值 */ 
static int flag; /* 節(jié)點增減標志 */ 
static int btree_level = 0/* 多路樹的高度 */ 
static int btree_count = 0/* 多路樹的鍵總數(shù) */ 
static int node_sum = 0/* 多路樹的節(jié)點總數(shù) */ 
static int level; /* 當前訪問的節(jié)點所處的高度 */ 
static btree NewTree; /* 在節(jié)點分割的時候指向新建的節(jié)點 */ 
static typekey InsKey; /* 要插入的鍵 */ 

btree search(typekey key, btree t) 

int i,j,m; 
level
=btree_level-1
while (level >= 0){ 
for(i=0, j=t->d-1; i t->k[m])?(i=m+1):(j=m)); 
if (key == t->k){ 
btree_disp 
= i; 
return t; 

if (key > t->k) /* i == t->d-1 時有可能出現(xiàn) */ 
i
++
= t->p; 
level
--

return NULL; 


btree insert(typekey key, btree t) 

level
=btree_level; 
InternalInsert(key, t); 
if (flag == 1/* 根節(jié)點滿之后,它被分割成兩個半滿節(jié)點 */ 
t
=NewRoot(t); /* 樹的高度增加 */ 
return t; 


void InternalInsert(typekey key, btree t) 

int i,j,m; 

level
--
if (level < 0){ /* 到達了樹的底部: 指出要做的插入 */ 
NewTree 
= NULL; /* 這個鍵沒有對應(yīng)的子樹 */ 
InsKey 
= key; /* 導致底層的葉子節(jié)點增加鍵值+空子樹對 */ 
btree_count
++
flag 
= 1/* 指示上層節(jié)點把返回的鍵插入其中 */ 
return

for(i=0, j=t->d-1; i t->k[m])?(i=m+1):(j=m)); 
if (key == t->k) { 
Error(
1,key); /* 鍵已經(jīng)在樹中 */ 
flag 
= 0
return

if (key > t->k) /* i == t->d-1 時有可能出現(xiàn) */ 
i
++
InternalInsert(key, t
->p); 

if (flag == 0
return
/* 有新鍵要插入到當前節(jié)點中 */ 
if (t->< 2*M) {/* 當前節(jié)點未滿 */ 
InsInNode(t, i); 
/* 把鍵值+子樹對插入當前節(jié)點中 */ 
flag 
= 0/* 指示上層節(jié)點沒有需要插入的鍵值+子樹,插入過程結(jié)束 */ 

else /* 當前節(jié)點已滿,則分割這個頁面并把鍵值+子樹對插入當前節(jié)點中 */ 
SplitNode(t, i); 
/* 繼續(xù)指示上層節(jié)點把返回的鍵值+子樹插入其中 */ 


/* 
* 把一個鍵和對應(yīng)的右子樹插入一個節(jié)點中 
*/ 
void InsInNode(btree t, int d) 

int i; 
/* 把所有大于要插入的鍵值的鍵和對應(yīng)的右子樹右移 */ 
for(i = t->d; i > d; i--){ 
t
->= t->k[i-1]; 
t
->= t->v[i-1]; 
t
->p[i+1= t->p; 

/* 插入鍵和右子樹 */ 
t
->= InsKey; 
t
->p[i+1= NewTree; 
t
->= InsValue; 
t
->d++

/* 
* 前件是要插入一個鍵和對應(yīng)的右子樹,并且本節(jié)點已經(jīng)滿 
* 導致分割這個節(jié)點,插入鍵和對應(yīng)的右子樹, 
* 并向上層返回一個要插入鍵和對應(yīng)的右子樹 
*/ 
void SplitNode(btree t, int d) 

int i,j; 
btree temp; 
typekey temp_k; 
char *temp_v; 
/* 建立新節(jié)點 */ 
temp 
= (btree)malloc(sizeof(node)); 
/* 
* +---+--------+-----+-----+--------+-----+ 
* | 0 | ...... | M | M+1 | ...... |2*M-1| 
* +---+--------+-----+-----+--------+-----+ 
* |<- M+1 ->|<- M-1 ->| 
*/ 
if (d > M) { /* 要插入當前節(jié)點的右半部分 */ 
/* 把從 2*M-1 到 M+1 的 M-1 個鍵值+子樹對轉(zhuǎn)移到新節(jié)點中, 
* 并且為要插入的鍵值+子樹空出位置 
*/ 
for(i=2*M-1,j=M-1; i>=d; i--,j--) { 
temp
->k[j] = t->k; 
temp
->v[j] = t->v; 
temp
->p[j+1= t->p[i+1]; 

for(i=d-1,j=d-M-2; j>=0; i--,j--) { 
temp
->k[j] = t->k; 
temp
->v[j] = t->v; 
temp
->p[j+1= t->p[i+1]; 

/* 把節(jié)點的最右子樹轉(zhuǎn)移成新節(jié)點的最左子樹 */ 
temp
->p[0= t->p[M+1]; 
/* 在新節(jié)點中插入鍵和右子樹 */ 
temp
->k[d-M-1= InsKey; 
temp
->p[d-M] = NewTree; 
temp
->v[d-M-1= InsValue; 
/* 設(shè)置要插入上層節(jié)點的鍵和值 */ 
InsKey 
= t->k[M]; 
InsValue 
= t->v[M]; 


else { /* d <= M */ 
/* 把從 2*M-1 到 M 的 M 個鍵值+子樹對轉(zhuǎn)移到新節(jié)點中 */ 
for(i=2*M-1,j=M-1; j>=0; i--,j--) { 
temp
->k[j] = t->k; 
temp
->v[j] = t->v; 
temp
->p[j+1= t->p[i+1]; 

if (d == M) /* 要插入當前節(jié)點的正中間 */ 
/* 把要插入的子樹作為新節(jié)點的最左子樹 */ 
temp
->p[0= NewTree; 
/* 直接把要插入的鍵和值返回給上層節(jié)點 */ 
else { /* (d /* 把節(jié)點當前的最右子樹轉(zhuǎn)移成新節(jié)點的最左子樹 */ 
temp
->p[0= t->p[M]; 
/* 保存要插入上層節(jié)點的鍵和值 */ 
temp_k 
= t->k[M-1]; 
temp_v 
= t->v[M-1]; 
/* 把所有大于要插入的鍵值的鍵和對應(yīng)的右子樹右移 */ 
for(i=M-1; i>d; i--) { 
t
->= t->k[i-1]; 
t
->= t->v[i-1]; 
t
->p[i+1= t->p; 

/* 在節(jié)點中插入鍵和右子樹 */ 
t
->k[d] = InsKey; 
t
->p[d+1= NewTree; 
t
->v[d] = InsValue; 
/* 設(shè)置要插入上層節(jié)點的鍵和值 */ 
InsKey 
= temp_k; 
InsValue 
= temp_v; 


t
->=M; 
temp
->= M; 
NewTree 
= temp; 
node_sum
++


btree delete(typekey key, btree t) 

level
=btree_level; 
InternalDelete(key, t); 
if (t->== 0
/* 根節(jié)點的子節(jié)點合并導致根節(jié)點鍵的數(shù)目隨之減少, 
* 當根節(jié)點中沒有鍵的時候,只有它的最左子樹可能非空 
*/ 
t
=FreeRoot(t); 
return t; 


void InternalDelete(typekey key, btree t) 

int i,j,m; 
btree l,r; 
int lvl; 

level
--
if (level < 0) { 
Error(
0,key); /* 在整個樹中未找到要刪除的鍵 */ 
flag 
= 0
return

for(i=0, j=t->d-1; i t->k[m])?(i=m+1):(j=m)); 
if (key == t->k) { /* 找到要刪除的鍵 */ 
if (t->!= NULL) 
free(t
->v); /* 釋放這個節(jié)點包含的值 */ 
if (level == 0) { /* 有子樹為空則這個鍵位于葉子節(jié)點 */ 
DelFromNode(t,i); 
btree_count
--
flag 
= 1
/* 指示上層節(jié)點本子樹的鍵數(shù)量減少 */ 
return
else { /* 這個鍵位于非葉節(jié)點 */ 
lvl 
= level-1
/* 找到前驅(qū)節(jié)點 */ 
= t->p; 
while (lvl > 0) { 
= r->p[r->d]; 
lvl
--

t
->k=r->k[r->d-1]; 
t
->v=r->v[r->d-1]; 
r
->v[r->d-1]=NULL; 
key 
= r->k[r->d-1]; 


else if (key > t->k) /* i == t->d-1 時有可能出現(xiàn) */ 
i
++
InternalDelete(key,t
->p); 
/* 調(diào)整平衡 */ 
if (flag == 0
return
if (t->p->< M) { 
if (i == t->d) /* 在最右子樹中發(fā)生了刪除 */ 
i
--/* 調(diào)整最右鍵的左右子樹平衡 */ 
= t->p; 
= t->p[i+1]; 
if (r->> M) 
MoveLeftNode(t,i); 
else if(l->> M) 
MoveRightNode(t,i); 
else { 
JoinNode(t,i); 
/* 繼續(xù)指示上層節(jié)點本子樹的鍵數(shù)量減少 */ 
return

flag 
= 0
/* 指示上層節(jié)點本子樹的鍵數(shù)量沒有減少,刪除過程結(jié)束 */ 



/* 
* 合并一個節(jié)點的某個鍵對應(yīng)的兩個子樹 
*/ 
void JoinNode(btree t, int d) 

btree l,r; 
int i,j; 
= t->p[d]; 
= t->p[d+1]; 

/* 把這個鍵下移到它的左子樹 */ 
l
->k[l->d] = t->k[d]; 
l
->v[l->d] = t->v[d]; 
/* 把右子樹中的所有鍵值和子樹轉(zhuǎn)移到左子樹 */ 
for (j=r->d-1,i=l->d+r->d; j >= 0 ; j--,i--) { 
l
->= r->k[j]; 
l
->= r->v[j]; 
l
->= r->p[j]; 

l
->p[l->d+r->d+1= r->p[r->d]; 
l
->+= r->d+1
/* 釋放右子樹的節(jié)點 */ 
free(r); 
/* 把這個鍵右邊的鍵和對應(yīng)的右子樹左移 */ 
for (i=d; i < t->d-1; i++) { 
t
->= t->k[i+1]; 
t
->= t->v[i+1]; 
t
->p[i+1= t->p[i+2]; 

t
->d--
node_sum
--

/* 
* 從一個鍵的右子樹向左子樹轉(zhuǎn)移一些鍵,使兩個子樹平衡 
*/ 
void MoveLeftNode(btree t, int d) 

btree l,r; 
int m; /* 應(yīng)轉(zhuǎn)移的鍵的數(shù)目 */ 
int i,j; 
= t->p[d]; 
= t->p[d+1]; 
= (r->- l->d)/2

/* 把這個鍵下移到它的左子樹 */ 
l
->k[l->d] = t->k[d]; 
l
->v[l->d] = t->v[d]; 
/* 把右子樹的最左子樹轉(zhuǎn)移成左子樹的最右子樹 
* 從右子樹向左子樹移動 m-1 個鍵+子樹對 
*/ 
for (j=m-2,i=l->d+m-1; j >= 0; j--,i--) { 
l
->= r->k[j]; 
l
->= r->v[j]; 
l
->= r->p[j]; 

l
->p[l->d+m] = r->p[m-1]; 
/* 把右子樹的最左鍵提升到這個鍵的位置上 */ 
t
->k[d] = r->k[m-1]; 
t
->v[d] = r->v[m-1]; 
/* 把右子樹中的所有鍵值和子樹左移 m 個位置 */ 
r
->p[0= r->p[m]; 
for (i=0; id-m; i++) { 
r
->= r->k[i+m]; 
r
->= r->v[i+m]; 
r
->= r->p[i+m]; 

r
->p[r->d-m] = r->p[r->d]; 
l
->d+=m; 
r
->d-=m; 

/* 
* 從一個鍵的左子樹向右子樹轉(zhuǎn)移一些鍵,使兩個子樹平衡 
*/ 
void MoveRightNode(btree t, int d) 

btree l,r; 
int m; /* 應(yīng)轉(zhuǎn)移的鍵的數(shù)目 */ 
int i,j; 
= t->p[d]; 
= t->p[d+1]; 

= (l->- r->d)/2
/* 把右子樹中的所有鍵值和子樹右移 m 個位置 */ 
r
->p[r->d+m]=r->p[r->d]; 
for (i=r->d-1; i>=0; i--) { 
r
->k[i+m] = r->k; 
r
->v[i+m] = r->v; 
r
->p[i+m] = r->p; 

/* 把這個鍵下移到它的右子樹 */ 
r
->k[m-1= t->k[d]; 
r
->v[m-1= t->v[d]; 
/* 把左子樹的最右子樹轉(zhuǎn)移成右子樹的最左子樹 */ 
r
->p[m-1= l->p[l->d]; 
/* 從左子樹向右子樹移動 m-1 個鍵+子樹對 */ 
for (i=l->d-1,j=m-2; j>=0; j--,i--) { 
r
->k[j] = l->k; 
r
->v[j] = l->v; 
r
->p[j] = l->p; 

/* 把左子樹的最右鍵提升到這個鍵的位置上 */ 
t
->k[d] = l->k; 
t
->v[d] = l->v; 
l
->d-=m; 
r
->d+=m; 

/* 
* 把一個鍵和對應(yīng)的右子樹從一個節(jié)點中刪除 
*/ 
void DelFromNode(btree t, int d) 

int i; 
/* 把所有大于要刪除的鍵值的鍵左移 */ 
for(i=d; i < t->d-1; i++) { 
t
->= t->k[i+1]; 
t
->= t->v[i+1]; 

t
->d--

/* 
* 建立有兩個子樹和一個鍵的根節(jié)點 
*/ 
btree NewRoot(btree t) 

btree temp; 
temp 
= (btree)malloc(sizeof(node)); 
temp
->= 1
temp
->p[0= t; 
temp
->p[1= NewTree; 
temp
->k[0= InsKey; 
temp
->v[0= InsValue; 
btree_level
++
node_sum
++
return(temp); 

/* 
* 釋放根節(jié)點,并返回它的最左子樹 
*/ 
btree FreeRoot(btree t) 

btree temp; 
temp 
= t->p[0]; 
free(t); 
btree_level
--
node_sum
--
return temp; 


void Error(int f,typekey key) 

if (f) 
printf(
"Btrees error: Insert %d! ",key); 
else 
printf(
"Btrees error: delete %d! ",key); 


int height(btree t) 

return btree_level; 


int count(btree t) 

return btree_count; 

double payload(btree t) 

if (node_sum==0
return 1
return (double)btree_count/(node_sum*(2*M)); 

btree deltree (btree t) 

level
=btree_level; 
btree_level 
= 0
return delall(t); 


btree delall(btree t) 

int i; 
level
--
if (level >= 0) { 
for (i=0; i < t->d; i++
if (t->!= NULL) 
free(t
->v); 
if (level > 0
for (i=0; i<= t->d ; i++
t
->p=delall(t->p); 
free(t); 

return NULL; 


/* end of btrees.c */ 

 

 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    久久精品国产亚洲av麻豆尤物| 一区二区三区亚洲天堂| 九九热精品视频免费在线播放| 国产亚洲神马午夜福利| 日韩精品毛片视频免费看| 男女午夜福利院在线观看| 日韩一区二区三区四区乱码视频| 免费观看在线午夜视频| 亚洲国产丝袜一区二区三区四| 中文文精品字幕一区二区| 国产午夜精品美女露脸视频| 国产亚洲欧美日韩国亚语| 不卡一区二区高清视频| 亚洲综合日韩精品欧美综合区| 欧美亚洲综合另类色妞| 亚洲午夜精品视频观看| 丰满人妻少妇精品一区二区三区| 99久久精品午夜一区| 国产精品视频一区麻豆专区 | 91久久国产福利自产拍 | 国产欧美一区二区久久| 手机在线不卡国产视频| 亚洲中文在线男人的天堂| 99亚洲综合精品成人网色播| 欧美一区二区三区播放| 国产国产精品精品在线| 后入美臀少妇一区二区| 欧美大黄片在线免费观看| 国产内射一级一片内射高清| 国产精品激情对白一区二区| 亚洲天堂国产精品久久精品| 日本一区二区三区黄色| 欧美性高清一区二区三区视频| 日韩一级欧美一级久久| 91在线播放在线播放观看| 国产精品视频一级香蕉| 成年人黄片大全在线观看| 国产三级欧美三级日韩三级 | 国产级别精品一区二区视频| 亚洲欧美日韩在线看片| 国产成人亚洲欧美二区综|