日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SQLite B+树实现代码

發布時間:2024/10/8 数据库 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQLite B+树实现代码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?
from http://www.sqlite.com.cn/MySqlite/6/373.Html

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

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

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

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

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;?/*?查找時找到的鍵在節點中的位置?*/?
char?*?InsValue?=?NULL;?/*?與要插的鍵相對應的值?*/?
static?int?flag;?/*?節點增減標志?*/?
static?int?btree_level?=?0;?/*?多路樹的高度?*/?
static?int?btree_count?=?0;?/*?多路樹的鍵總數?*/?
static?int?node_sum?=?0;?/*?多路樹的節點總數?*/?
static?int?level;?/*?當前訪問的節點所處的高度?*/?
static?btree?NewTree;?/*?在節點分割的時候指向新建的節點?*/?
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?時有可能出現?*/?
i
++;?
t?
=?t->p;?
level
--;?
}?
return?NULL;?
}?

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

void?InternalInsert(typekey?key,?btree?t)?
{?
int?i,j,m;?

level
--;?
if?(level?<?0){?/*?到達了樹的底部:?指出要做的插入?*/?
NewTree?
=?NULL;?/*?這個鍵沒有對應的子樹?*/?
InsKey?
=?key;?/*?導致底層的葉子節點增加鍵值+空子樹對?*/?
btree_count
++;?
flag?
=?1;?/*?指示上層節點把返回的鍵插入其中?*/?
return;?
}?
for(i=0,?j=t->d-1;?i?t->k[m])?(i=m+1):(j=m));?
if?(key?==?t->k)?{?
Error(
1,key);?/*?鍵已經在樹中?*/?
flag?
=?0;?
return;?
}?
if?(key?>?t->k)?/*?i?==?t->d-1?時有可能出現?*/?
i
++;?
InternalInsert(key,?t
->p);?

if?(flag?==?0)?
return;?
/*?有新鍵要插入到當前節點中?*/?
if?(t->d?<?2*M)?{/*?當前節點未滿?*/?
InsInNode(t,?i);?
/*?把鍵值+子樹對插入當前節點中?*/?
flag?
=?0;?/*?指示上層節點沒有需要插入的鍵值+子樹,插入過程結束?*/?
}?
else?/*?當前節點已滿,則分割這個頁面并把鍵值+子樹對插入當前節點中?*/?
SplitNode(t,?i);?
/*?繼續指示上層節點把返回的鍵值+子樹插入其中?*/?
}?

/*?
*?把一個鍵和對應的右子樹插入一個節點中?
*/?
void?InsInNode(btree?t,?int?d)?
{?
int?i;?
/*?把所有大于要插入的鍵值的鍵和對應的右子樹右移?*/?
for(i?=?t->d;?i?>?d;?i--){?
t
->k?=?t->k[i-1];?
t
->v?=?t->v[i-1];?
t
->p[i+1]?=?t->p;?
}?
/*?插入鍵和右子樹?*/?
t
->k?=?InsKey;?
t
->p[i+1]?=?NewTree;?
t
->v?=?InsValue;?
t
->d++;?
}?
/*?
*?前件是要插入一個鍵和對應的右子樹,并且本節點已經滿?
*?導致分割這個節點,插入鍵和對應的右子樹,?
*?并向上層返回一個要插入鍵和對應的右子樹?
*/?
void?SplitNode(btree?t,?int?d)?
{?
int?i,j;?
btree?temp;?
typekey?temp_k;?
char?*temp_v;?
/*?建立新節點?*/?
temp?
=?(btree)malloc(sizeof(node));?
/*?
*?+---+--------+-----+-----+--------+-----+?
*?|?0?|??|?M?|?M+1?|??|2*M-1|?
*?+---+--------+-----+-----+--------+-----+?
*?|<-?M+1?->|<-?M-1?->|?
*/?
if?(d?>?M)?{?/*?要插入當前節點的右半部分?*/?
/*?把從?2*M-1?到?M+1?的?M-1?個鍵值+子樹對轉移到新節點中,?
*?并且為要插入的鍵值+子樹空出位置?
*/?
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];?
}?
/*?把節點的最右子樹轉移成新節點的最左子樹?*/?
temp
->p[0]?=?t->p[M+1];?
/*?在新節點中插入鍵和右子樹?*/?
temp
->k[d-M-1]?=?InsKey;?
temp
->p[d-M]?=?NewTree;?
temp
->v[d-M-1]?=?InsValue;?
/*?設置要插入上層節點的鍵和值?*/?
InsKey?
=?t->k[M];?
InsValue?
=?t->v[M];?

}?
else?{?/*?d?<=?M?*/?
/*?把從?2*M-1?到?M?的?M?個鍵值+子樹對轉移到新節點中?*/?
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)?/*?要插入當前節點的正中間?*/?
/*?把要插入的子樹作為新節點的最左子樹?*/?
temp
->p[0]?=?NewTree;?
/*?直接把要插入的鍵和值返回給上層節點?*/?
else?{?/*?(d?/*?把節點當前的最右子樹轉移成新節點的最左子樹?*/?
temp
->p[0]?=?t->p[M];?
/*?保存要插入上層節點的鍵和值?*/?
temp_k?
=?t->k[M-1];?
temp_v?
=?t->v[M-1];?
/*?把所有大于要插入的鍵值的鍵和對應的右子樹右移?*/?
for(i=M-1;?i>d;?i--)?{?
t
->k?=?t->k[i-1];?
t
->v?=?t->v[i-1];?
t
->p[i+1]?=?t->p;?
}?
/*?在節點中插入鍵和右子樹?*/?
t
->k[d]?=?InsKey;?
t
->p[d+1]?=?NewTree;?
t
->v[d]?=?InsValue;?
/*?設置要插入上層節點的鍵和值?*/?
InsKey?
=?temp_k;?
InsValue?
=?temp_v;?
}?
}?
t
->d?=M;?
temp
->d?=?M;?
NewTree?
=?temp;?
node_sum
++;?
}?

btree?delete(typekey?key,?btree?t)?
{?
level
=btree_level;?
InternalDelete(key,?t);?
if?(t->d?==?0)?
/*?根節點的子節點合并導致根節點鍵的數目隨之減少,?
*?當根節點中沒有鍵的時候,只有它的最左子樹可能非空?
*/?
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->v?!=?NULL)?
free(t
->v);?/*?釋放這個節點包含的值?*/?
if?(level?==?0)?{?/*?有子樹為空則這個鍵位于葉子節點?*/?
DelFromNode(t,i);?
btree_count
--;?
flag?
=?1;?
/*?指示上層節點本子樹的鍵數量減少?*/?
return;?
}?
else?{?/*?這個鍵位于非葉節點?*/?
lvl?
=?level-1;?
/*?找到前驅節點?*/?
r?
=?t->p;?
while?(lvl?>?0)?{?
r?
=?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?時有可能出現?*/?
i
++;?
InternalDelete(key,t
->p);?
/*?調整平衡?*/?
if?(flag?==?0)?
return;?
if?(t->p->d?<?M)?{?
if?(i?==?t->d)?/*?在最右子樹中發生了刪除?*/?
i
--;?/*?調整最右鍵的左右子樹平衡?*/?
l?
=?t->p;?
r?
=?t->p[i+1];?
if?(r->d?>?M)?
MoveLeftNode(t,i);?
else?if(l->d?>?M)?
MoveRightNode(t,i);?
else?{?
JoinNode(t,i);?
/*?繼續指示上層節點本子樹的鍵數量減少?*/?
return;?
}?
flag?
=?0;?
/*?指示上層節點本子樹的鍵數量沒有減少,刪除過程結束?*/?
}?
}?

/*?
*?合并一個節點的某個鍵對應的兩個子樹?
*/?
void?JoinNode(btree?t,?int?d)?
{?
btree?l,r;?
int?i,j;?
l?
=?t->p[d];?
r?
=?t->p[d+1];?

/*?把這個鍵下移到它的左子樹?*/?
l
->k[l->d]?=?t->k[d];?
l
->v[l->d]?=?t->v[d];?
/*?把右子樹中的所有鍵值和子樹轉移到左子樹?*/?
for?(j=r->d-1,i=l->d+r->d;?j?>=?0?;?j--,i--)?{?
l
->k?=?r->k[j];?
l
->v?=?r->v[j];?
l
->p?=?r->p[j];?
}?
l
->p[l->d+r->d+1]?=?r->p[r->d];?
l
->d?+=?r->d+1;?
/*?釋放右子樹的節點?*/?
free(r);?
/*?把這個鍵右邊的鍵和對應的右子樹左移?*/?
for?(i=d;?i?<?t->d-1;?i++)?{?
t
->k?=?t->k[i+1];?
t
->v?=?t->v[i+1];?
t
->p[i+1]?=?t->p[i+2];?
}?
t
->d--;?
node_sum
--;?
}?
/*?
*?從一個鍵的右子樹向左子樹轉移一些鍵,使兩個子樹平衡?
*/?
void?MoveLeftNode(btree?t,?int?d)?
{?
btree?l,r;?
int?m;?/*?應轉移的鍵的數目?*/?
int?i,j;?
l?
=?t->p[d];?
r?
=?t->p[d+1];?
m?
=?(r->d?-?l->d)/2;?

/*?把這個鍵下移到它的左子樹?*/?
l
->k[l->d]?=?t->k[d];?
l
->v[l->d]?=?t->v[d];?
/*?把右子樹的最左子樹轉移成左子樹的最右子樹?
*?從右子樹向左子樹移動?m-1?個鍵+子樹對?
*/?
for?(j=m-2,i=l->d+m-1;?j?>=?0;?j--,i--)?{?
l
->k?=?r->k[j];?
l
->v?=?r->v[j];?
l
->p?=?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
->k?=?r->k[i+m];?
r
->v?=?r->v[i+m];?
r
->p?=?r->p[i+m];?
}?
r
->p[r->d-m]?=?r->p[r->d];?
l
->d+=m;?
r
->d-=m;?
}?
/*?
*?從一個鍵的左子樹向右子樹轉移一些鍵,使兩個子樹平衡?
*/?
void?MoveRightNode(btree?t,?int?d)?
{?
btree?l,r;?
int?m;?/*?應轉移的鍵的數目?*/?
int?i,j;?
l?
=?t->p[d];?
r?
=?t->p[d+1];?

m?
=?(l->d?-?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];?
/*?把左子樹的最右子樹轉移成右子樹的最左子樹?*/?
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;?
}?
/*?
*?把一個鍵和對應的右子樹從一個節點中刪除?
*/?
void?DelFromNode(btree?t,?int?d)?
{?
int?i;?
/*?把所有大于要刪除的鍵值的鍵左移?*/?
for(i=d;?i?<?t->d-1;?i++)?{?
t
->k?=?t->k[i+1];?
t
->v?=?t->v[i+1];?
}?
t
->d--;?
}?
/*?
*?建立有兩個子樹和一個鍵的根節點?
*/?
btree?NewRoot(btree?t)?
{?
btree?temp;?
temp?
=?(btree)malloc(sizeof(node));?
temp
->d?=?1;?
temp
->p[0]?=?t;?
temp
->p[1]?=?NewTree;?
temp
->k[0]?=?InsKey;?
temp
->v[0]?=?InsValue;?
btree_level
++;?
node_sum
++;?
return(temp);?
}?
/*?
*?釋放根節點,并返回它的最左子樹?
*/?
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->v?!=?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?*/?

轉載于:https://www.cnblogs.com/jojoke/archive/2007/04/13/712210.html

總結

以上是生活随笔為你收集整理的SQLite B+树实现代码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。