1.b树的定义
b树是一种平衡的多路查找树,他在文件系统很有用。
一颗m阶的B树,或为空树,或者满足依稀阿特性的M叉树;
- 每个结点至多拥有M课子树
- 根结点至少拥有两颗子树
- 除了根结点以外,其余每个分支结点至少拥有M/2课子树
- 所有的叶结点都在同一层上
- 有k课子树的分支结点则存在k-1个关键字,关键字按照递增顺序进行排序
- 关键字数量满足ceil(M/2)-1 <= n <= M-1
2.B树的数据结构
//这样子定义阶,阶是偶数,key的数量就是奇数了,方便分裂的时候找到最中间的key
#define M 4 //阶为2M
#define KEY_NUM (2 * M - 1) //key的数量
typedef int type_t;
typedef struct btree_t
{
int num; /* number of keys */
char leaf; /* if or not is a leaf */
type_t key[KEY_NUM];
struct btree_t* child[KEY_NUM + 1];
}btree_t, btnode_t;
3.插入的情况分析
1)根据要插入的key的值,找到叶子结点并插入。
2)判断当前结点key的个数是否小于等于m-1,若满足则结束,否则进行第3步。
3)以结点中间的key为中心分裂成左右两部分,然后将这个中间的key插入到父结点中,这个key的左子树指向分裂后的左半部分,这个key的右子支指向分裂后的右半部分,
4)然后将当前结点指向父结点,继续进行第2步,直到结束。
4.删除的情况分析
1)如果当前需要删除的key位于非叶子结点上,则寻找后继key来覆盖要删除的key,当前需要删除的节点指向后继key。
2)当前结点key个数大于等于Math.ceil(m/2)-1,结束删除操作,否则执行第3步。
3)如果左边兄弟结点key个数大于Math.ceil(m/2)-1,则父结点中的key下移到该结点,兄弟结点中的一个key上移,删除操作结束,否则执行第4步。
4)如果右边兄弟结点key个数大于Math.ceil(m/2)-1,则父结点中的key下移到该结点,兄弟结点中的一个key上移,删除操作结束,否则执行第5步。
5)这时候左边兄弟节点和右边兄弟节点肯定有一个等于Math.ceil(m/2)-1,可以将父结点中的key下移与当前结点及它的兄弟结点中的key合并,形成一个新的结点。原父结点中的key的两个孩子指针就变成了一个孩子指针,指向这个新结点。然后当前结点的指针指向父结点。(注意:将父结点下移,则父节点少了一个节点,就是相当于删除了一个父节点。)
6)重复上面的第2步。