文章目录
在本教程中,您将学习如何将key插入B树。此外,您还可以找到C语言的示例。
在B树上插入元素包含两个事件:搜索适当的节点以插入元素,在需要的时候拆分节点。插入操作总是以自下而上的方式进行。
让我们了解下面这些事件。
1. 插入操作
- 如果树为空,则分配根节点并插入键。
- 更新节点中允许的键数。
- 搜索适当的节点以进行插入。
- 如果节点已满,请执行以下步骤。
- 按递增顺序插入元素。
- 现在,有一些元素超出了其限制。因此,在中位数处进行拆分。
- 向上提升中间键,将左键设为左子级,将右键设为右子级。
- 如果节点未满,请执行以下步骤。
- 按递增顺序插入节点。
2. 插入过程图示
让我们通过下面的插图来了解插入操作。
要插入的元素有8、9、10、11、15、16、17、18、20、23。
3. 插入元素的算法
BreeInsertion(T, k)
r root[T]
if n[r] = 2t - 1
s = AllocateNode()
root[T] = s
leaf[s] = FALSE
n[s] <- 0
c1[s] <- r
BtreeSplitChild(s, 1, r)
BtreeInsertNonFull(s, k)
else BtreeInsertNonFull(r, k)
BtreeInsertNonFull(x, k)
i = n[x]
if leaf[x]
while i ≥ 1 and k < keyi[x]
keyi+1 [x] = keyi[x]
i = i - 1
keyi+1[x] = k
n[x] = n[x] + 1
else while i ≥ 1 and k < keyi[x]
i = i - 1
i = i + 1
if n[ci[x]] == 2t - 1
BtreeSplitChild(x, i, ci[x])
if k &rt; keyi[x]
i = i + 1
BtreeInsertNonFull(ci[x], k)
BtreeSplitChild(x, i)
BtreeSplitChild(x, i, y)
z = AllocateNode()
leaf[z] = leaf[y]
n[z] = t - 1
for j = 1 to t - 1
keyj[z] = keyj+t[y]
if not leaf [y]
for j = 1 to t
cj[z] = cj + t[y]
n[y] = t - 1
for j = n[x] + 1 to i + 1
cj+1[x] = cj[x]
ci+1[x] = z
for j = n[x] to i
keyj+1[x] = keyj[x]
keyi[x] = keyt[y]
n[x] = n[x] + 1
4. C示例
// insertioning a key on a B-tree in C
#include <stdio.h>
#include <stdlib.h>
#define MAX 3
#define MIN 2
struct btreeNode {
int item[MAX + 1], count;
struct btreeNode *link[MAX + 1];
};
struct btreeNode *root;
// Node creation
struct btreeNode *createNode(int item, struct btreeNode *child) {
struct btreeNode *newNode;
newNode = (struct btreeNode *)malloc(sizeof(struct btreeNode));
newNode->item[1] = item;
newNode->count = 1;
newNode->link[0] = root;
newNode->link[1] = child;
return newNode;
}
// Insert
void insertValue(int item, int pos, struct btreeNode *node,
struct btreeNode *child) {
int j = node->count;
while (j > pos) {
node->item[j + 1] = node->item[j];
node->link[j + 1] = node->link[j];
j--;
}
node->item[j + 1] = item;
node->link[j + 1] = child;
node->count++;
}
// Split node
void splitNode(int item, int *pval, int pos, struct btreeNode *node,
struct btreeNode *child, struct btreeNode **newNode) {
int median, j;
if (pos > MIN)
median = MIN + 1;
else
median = MIN;
*newNode = (struct btreeNode *)malloc(sizeof(struct btreeNode));
j = median + 1;
while (j <= MAX) {
(*newNode)->item[j - median] = node->item[j];
(*newNode)->link[j - median] = node->link[j];
j++;
}
node->count = median;
(*newNode)->count = MAX - median;
if (pos <= MIN) {
insertValue(item, pos, node, child);
} else {
insertValue(item, pos - median, *newNode, child);
}
*pval = node->item[node->count];
(*newNode)->link[0] = node->link[node->count];
node->count--;
}
// Set the value of node
int setNodeValue(int item, int *pval,
struct btreeNode *node, struct btreeNode **child) {
int pos;
if (!node) {
*pval = item;
*child = NULL;
return 1;
}
if (item < node->item[1]) {
pos = 0;
} else {
for (pos = node->count;
(item < node->item[pos] && pos > 1); pos--)
;
if (item == node->item[pos]) {
printf("Duplicates not allowed\n");
return 0;
}
}
if (setNodeValue(item, pval, node->link[pos], child)) {
if (node->count < MAX) {
insertValue(*pval, pos, node, *child);
} else {
splitNode(*pval, pval, pos, node, *child, child);
return 1;
}
}
return 0;
}
// Insert the value
void insertion(int item) {
int flag, i;
struct btreeNode *child;
flag = setNodeValue(item, &i, root, &child);
if (flag)
root = createNode(i, child);
}
// Copy the successor
void copySuccessor(struct btreeNode *myNode, int pos) {
struct btreeNode *dummy;
dummy = myNode->link[pos];
for (; dummy->link[0] != NULL;)
dummy = dummy->link[0];
myNode->item[pos] = dummy->item[1];
}
// Do rightshift
void rightShift(struct btreeNode *myNode, int pos) {
struct btreeNode *x = myNode->link[pos];
int j = x->count;
while (j > 0) {
x->item[j + 1] = x->item[j];
x->link[j + 1] = x->link[j];
}
x->item[1] = myNode->item[pos];
x->link[1] = x->link[0];
x->count++;
x = myNode->link[pos - 1];
myNode->item[pos] = x->item[x->count];
myNode->link[pos] = x->link[x->count];
x->count--;
return;
}
// Do leftshift
void leftShift(struct btreeNode *myNode, int pos) {
int j = 1;
struct btreeNode *x = myNode->link[pos - 1];
x->count++;
x->item[x->count] = myNode->item[pos];
x->link[x->count] = myNode->link[pos]->link[0];
x = myNode->link[pos];
myNode->item[pos] = x->item[1];
x->link[0] = x->link[1];
x->count--;
while (j <= x->count) {
x->item[j] = x->item[j + 1];
x->link[j] = x->link[j + 1];
j++;
}
return;
}
// Merge the nodes
void mergeNodes(struct btreeNode *myNode, int pos) {
int j = 1;
struct btreeNode *x1 = myNode->link[pos], *x2 = myNode->link[pos - 1];
x2->count++;
x2->item[x2->count] = myNode->item[pos];
x2->link[x2->count] = myNode->link[0];
while (j <= x1->count) {
x2->count++;
x2->item[x2->count] = x1->item[j];
x2->link[x2->count] = x1->link[j];
j++;
}
j = pos;
while (j < myNode->count) {
myNode->item[j] = myNode->item[j + 1];
myNode->link[j] = myNode->link[j + 1];
j++;
}
myNode->count--;
free(x1);
}
// Adjust the node
void adjustNode(struct btreeNode *myNode, int pos) {
if (!pos) {
if (myNode->link[1]->count > MIN) {
leftShift(myNode, 1);
} else {
mergeNodes(myNode, 1);
}
} else {
if (myNode->count != pos) {
if (myNode->link[pos - 1]->count > MIN) {
rightShift(myNode, pos);
} else {
if (myNode->link[pos + 1]->count > MIN) {
leftShift(myNode, pos + 1);
} else {
mergeNodes(myNode, pos);
}
}
} else {
if (myNode->link[pos - 1]->count > MIN)
rightShift(myNode, pos);
else
mergeNodes(myNode, pos);
}
}
}
// Traverse the tree
void traversal(struct btreeNode *myNode) {
int i;
if (myNode) {
for (i = 0; i < myNode->count; i++) {
traversal(myNode->link[i]);
printf("%d ", myNode->item[i + 1]);
}
traversal(myNode->link[i]);
}
}
int main() {
int item, ch;
insertion(8);
insertion(9);
insertion(10);
insertion(11);
insertion(15);
insertion(16);
insertion(17);
insertion(18);
insertion(20);
insertion(23);
traversal(root);
}
参考文档
[1]Parewa Labs Pvt. Ltd.Insertion into a B-tree[EB/OL].https://www.programiz.com/dsa/insertion-into-a-b-tree,2020-01-01.