B树与B+树

B树的性质

一颗M阶B树T,满足以下条件
1.每个节点至多拥有M颗子树
2.根节点至少拥有两颗子树
3.除了根节点以外,其余每个分支结点至少拥有M/2颗子树
4. 所有的叶节点都在同一层上
5. 有k颗子树的分支结点则存在k-1个关键字,关键字按照递增顺序进行排序
6. 每个非根节点所包含的关键字数量满足ceil(M/2)-1 <= n <= M-1

B树的作用

磁盘存储,是采用B树的结构。磁盘的一个扇区,相当于B树的一个节点。使用B树,存储的层数降低了,使得查找性能的效率提升了。

B树的添加

1.先判断结点里的关键字数量是否等于M-1了
2.如果是的话,分裂
两种情况:
1) 如果分裂的是根节点,那么1节点分裂成3节点
2) 如果不是,那么1节点分裂成2节点

3.如果不是的,对结点的Key进行对比,找到合适的位置

btree_node *btree_create_node(int leaf) {

	btree_node *node = (btree_node*)calloc(1, sizeof(btree_node));
	if (node == NULL) assert(0);

	node->leaf = leaf;
	node->keys = (KEY_VALUE*)calloc(1, (M-1)*sizeof(KEY_VALUE));
	node->childrens = (btree_node**)calloc(1, M * sizeof(btree_node));
	node->num = 0;

	return node;
}

// 对插入的节点,进行分裂
void btree_split_child(btree *T, btree_node *x, int i) {
	int t = T->t;

	btree_node *y = x->childrens[i];
	btree_node *z = btree_create_node(t, y->leaf);

	z->num = t - 1;

	int j = 0;
	for (j = 0;j < t-1;j ++) {
		z->keys[j] = y->keys[j+t];
	}
	if (y->leaf == 0) {
		for (j = 0;j < t;j ++) {
			z->childrens[j] = y->childrens[j+t];
		}
	}

	y->num = t - 1;
	for (j = x->num;j >= i+1;j --) {
		x->childrens[j+1] = x->childrens[j];
	}

	x->childrens[i+1] = z;

	for (j = x->num-1;j >= i;j --) {
		x->keys[j+1] = x->keys[j];
	}
	x->keys[i] = y->keys[t-1];
	x->num += 1;
	
}


void btree_insert(btree *T, KEY_VALUE key) {
	
	btree_node *r = T->root;
	// M 指M阶的B树
	if (r->num == M - 1) {
		
		btree_node *node = btree_create_node(M, 0);
		T->root = node;

		node->childrens[0] = r;

		btree_split_child(T, node, 0);

		int i = 0;
		if (node->keys[0] < key) i++;
		btree_insert_nonfull(T, node->childrens[i], key);
		
	} else {
		btree_insert_nonfull(T, r, key);
	}
}

// 将要插入的节点没有满,直接插入
void btree_insert_nonfull(btree *T, btree_node *x, KEY_VALUE k) {

	int i = x->num - 1;

	if (x->leaf == 1) {
		// 对于叶节点,只需要找到合适的位置,把原来的有数据依次往后挪一位,再把数据插入
		while (i >= 0 && x->keys[i] > k) {
			x->keys[i+1] = x->keys[i];
			i --;
		}
		x->keys[i+1] = k;
		x->num += 1;
		
	} else {
		// 对于非叶子节点,先找到合适的位置,再判断它的孩子节点满了没有,满了先分裂再插入,没满继续往下层节点递归寻找
		while (i >= 0 && x->keys[i] > k) i --;

		if (x->childrens[i+1]->num == M-1) {
			btree_split_child(T, x, i+1);
			if (k > x->keys[i+1]) i++;
		}

		btree_insert_nonfull(T, x->childrens[i+1], k);
	}
}

B树与B+树的区别?

  1. B+树中只有叶子节点会带有指向数据记录的指针(ROWID),而B树则所有节点都带有,在内部节点出现的索引项不会再出现在叶子节点中。

  2. B+树中所有叶子节点都是通过指针连接在一起,而B树不会。

B+树的优点:

  1. 非叶子节点不会带上ROWID,这样,一个块中可以容纳更多的索引项,一是可以降低树的高度。二是一个内部节点可以定位更多的叶子节点。

  2. 叶子节点之间通过指针来连接,范围扫描将十分简单,而对于B树来说,则需要在叶子节点和内部节点不停的往返移动。

B树的优点:

对于在内部节点的数据,可直接得到,不必根据叶子节点来定位。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值