原文: https://www.programiz.com/dsa/insertion-into-a-b-tree

在本教程中,您将学习如何将键插入 B 树。 此外,您还将找到在 C,C++ ,Java 和 Python 中将键插入 B 树的工作示例。

在 B 树上插入元素包括两个事件:搜索适当的节点来插入元素,以及拆分节点。如有必要,插入操作始终从下往上进行。

让我们在下面了解这些事件。


插入操作

  1. 如果树为空,请分配一个根节点并插入键。
  2. 更新节点中允许的键数。
  3. 搜索适当的节点以进行插入。
  4. 如果节点已满,请执行以下步骤。
  5. 按递增顺序插入元素。
  6. 现在,有一些元素超出了其限制。 因此,将中位数拆分。
  7. 向上推中键,将左键作为左子代,将右键作为右子代。
  8. 如果节点未满,请执行以下步骤。
  9. 按升序插入节点。

插入示例

让我们通过以下插图了解插入操作。

要插入的元素是 8、9、10、11、15、16、17、18、20、23。

插入 B 树 - 图1

将元素插入 B 树


元素插入算法

  1. BreeInsertion(T, k)
  2. r root[T]
  3. if n[r] = 2t - 1
  4. s = AllocateNode()
  5. root[T] = s
  6. leaf[s] = FALSE
  7. n[s] <- 0
  8. c1[s] <- r
  9. BtreeSplitChild(s, 1, r)
  10. BtreeInsertNonFull(s, k)
  11. else BtreeInsertNonFull(r, k)
  12. BtreeInsertNonFull(x, k)
  13. i = n[x]
  14. if leaf[x]
  15. while i 1 and k < keyi[x]
  16. keyi+1 [x] = keyi[x]
  17. i = i - 1
  18. keyi+1[x] = k
  19. n[x] = n[x] + 1
  20. else while i 1 and k < keyi[x]
  21. i = i - 1
  22. i = i + 1
  23. if n[ci[x]] == 2t - 1
  24. BtreeSplitChild(x, i, ci[x])
  25. if k &rt; keyi[x]
  26. i = i + 1
  27. BtreeInsertNonFull(ci[x], k)
  28. BtreeSplitChild(x, i)
  29. BtreeSplitChild(x, i, y)
  30. z = AllocateNode()
  31. leaf[z] = leaf[y]
  32. n[z] = t - 1
  33. for j = 1 to t - 1
  34. keyj[z] = keyj+t[y]
  35. if not leaf [y]
  36. for j = 1 to t
  37. cj[z] = cj + t[y]
  38. n[y] = t - 1
  39. for j = n[x] + 1 to i + 1
  40. cj+1[x] = cj[x]
  41. ci+1[x] = z
  42. for j = n[x] to i
  43. keyj+1[x] = keyj[x]
  44. keyi[x] = keyt[y]
  45. n[x] = n[x] + 1

Python,Java 和 C/C++ 示例

  1. # Inserting a key on a B-tree in Python
  2. # Create a node
  3. class BTreeNode:
  4. def __init__(self, leaf=False):
  5. self.leaf = leaf
  6. self.keys = []
  7. self.child = []
  8. # Tree
  9. class BTree:
  10. def __init__(self, t):
  11. self.root = BTreeNode(True)
  12. self.t = t
  13. # Insert node
  14. def insert(self, k):
  15. root = self.root
  16. if len(root.keys) == (2 * self.t) - 1:
  17. temp = BTreeNode()
  18. self.root = temp
  19. temp.child.insert(0, root)
  20. self.split_child(temp, 0)
  21. self.insert_non_full(temp, k)
  22. else:
  23. self.insert_non_full(root, k)
  24. # Insert nonfull
  25. def insert_non_full(self, x, k):
  26. i = len(x.keys) - 1
  27. if x.leaf:
  28. x.keys.append((None, None))
  29. while i >= 0 and k[0] < x.keys[i][0]:
  30. x.keys[i + 1] = x.keys[i]
  31. i -= 1
  32. x.keys[i + 1] = k
  33. else:
  34. while i >= 0 and k[0] < x.keys[i][0]:
  35. i -= 1
  36. i += 1
  37. if len(x.child[i].keys) == (2 * self.t) - 1:
  38. self.split_child(x, i)
  39. if k[0] > x.keys[i][0]:
  40. i += 1
  41. self.insert_non_full(x.child[i], k)
  42. # Split the child
  43. def split_child(self, x, i):
  44. t = self.t
  45. y = x.child[i]
  46. z = BTreeNode(y.leaf)
  47. x.child.insert(i + 1, z)
  48. x.keys.insert(i, y.keys[t - 1])
  49. z.keys = y.keys[t: (2 * t) - 1]
  50. y.keys = y.keys[0: t - 1]
  51. if not y.leaf:
  52. z.child = y.child[t: 2 * t]
  53. y.child = y.child[0: t - 1]
  54. # Print the tree
  55. def print_tree(self, x, l=0):
  56. print("Level ", l, " ", len(x.keys), end=":")
  57. for i in x.keys:
  58. print(i, end=" ")
  59. print()
  60. l += 1
  61. if len(x.child) > 0:
  62. for i in x.child:
  63. self.print_tree(i, l)
  64. def main():
  65. B = BTree(3)
  66. for i in range(10):
  67. B.insert((i, 2 * i))
  68. B.print_tree(B.root)
  69. if __name__ == '__main__':
  70. main()
  1. // Inserting a key on a B-tree in Java
  2. public class BTree {
  3. private int T;
  4. // Node Creation
  5. public class Node {
  6. int n;
  7. int key[] = new int[2 * T - 1];
  8. Node child[] = new Node[2 * T];
  9. boolean leaf = true;
  10. public int Find(int k) {
  11. for (int i = 0; i < this.n; i++) {
  12. if (this.key[i] == k) {
  13. return i;
  14. }
  15. }
  16. return -1;
  17. };
  18. }
  19. public BTree(int t) {
  20. T = t;
  21. root = new Node();
  22. root.n = 0;
  23. root.leaf = true;
  24. }
  25. private Node root;
  26. // split
  27. private void split(Node x, int pos, Node y) {
  28. Node z = new Node();
  29. z.leaf = y.leaf;
  30. z.n = T - 1;
  31. for (int j = 0; j < T - 1; j++) {
  32. z.key[j] = y.key[j + T];
  33. }
  34. if (!y.leaf) {
  35. for (int j = 0; j < T; j++) {
  36. z.child[j] = y.child[j + T];
  37. }
  38. }
  39. y.n = T - 1;
  40. for (int j = x.n; j >= pos + 1; j--) {
  41. x.child[j + 1] = x.child[j];
  42. }
  43. x.child[pos + 1] = z;
  44. for (int j = x.n - 1; j >= pos; j--) {
  45. x.key[j + 1] = x.key[j];
  46. }
  47. x.key[pos] = y.key[T - 1];
  48. x.n = x.n + 1;
  49. }
  50. // insert key
  51. public void insert(final int key) {
  52. Node r = root;
  53. if (r.n == 2 * T - 1) {
  54. Node s = new Node();
  55. root = s;
  56. s.leaf = false;
  57. s.n = 0;
  58. s.child[0] = r;
  59. split(s, 0, r);
  60. _insert(s, key);
  61. } else {
  62. _insert(r, key);
  63. }
  64. }
  65. // insert node
  66. final private void _insert(Node x, int k) {
  67. if (x.leaf) {
  68. int i = 0;
  69. for (i = x.n - 1; i >= 0 && k < x.key[i]; i--) {
  70. x.key[i + 1] = x.key[i];
  71. }
  72. x.key[i + 1] = k;
  73. x.n = x.n + 1;
  74. } else {
  75. int i = 0;
  76. for (i = x.n - 1; i >= 0 && k < x.key[i]; i--) {
  77. }
  78. ;
  79. i++;
  80. Node tmp = x.child[i];
  81. if (tmp.n == 2 * T - 1) {
  82. split(x, i, tmp);
  83. if (k > x.key[i]) {
  84. i++;
  85. }
  86. }
  87. _insert(x.child[i], k);
  88. }
  89. }
  90. public void display() {
  91. display(root);
  92. }
  93. // Display the tree
  94. private void display(Node x) {
  95. assert (x == null);
  96. for (int i = 0; i < x.n; i++) {
  97. System.out.print(x.key[i] + " ");
  98. }
  99. if (!x.leaf) {
  100. for (int i = 0; i < x.n + 1; i++) {
  101. display(x.child[i]);
  102. }
  103. }
  104. }
  105. public static void main(String[] args) {
  106. BTree b = new BTree(3);
  107. b.insert(8);
  108. b.insert(9);
  109. b.insert(10);
  110. b.insert(11);
  111. b.insert(15);
  112. b.insert(20);
  113. b.insert(17);
  114. b.display();
  115. }
  116. }
  1. // insertioning a key on a B-tree in C
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #define MAX 3
  5. #define MIN 2
  6. struct btreeNode {
  7. int item[MAX + 1], count;
  8. struct btreeNode *link[MAX + 1];
  9. };
  10. struct btreeNode *root;
  11. // Node creation
  12. struct btreeNode *createNode(int item, struct btreeNode *child) {
  13. struct btreeNode *newNode;
  14. newNode = (struct btreeNode *)malloc(sizeof(struct btreeNode));
  15. newNode->item[1] = item;
  16. newNode->count = 1;
  17. newNode->link[0] = root;
  18. newNode->link[1] = child;
  19. return newNode;
  20. }
  21. // Insert
  22. void insertValue(int item, int pos, struct btreeNode *node,
  23. struct btreeNode *child) {
  24. int j = node->count;
  25. while (j > pos) {
  26. node->item[j + 1] = node->item[j];
  27. node->link[j + 1] = node->link[j];
  28. j--;
  29. }
  30. node->item[j + 1] = item;
  31. node->link[j + 1] = child;
  32. node->count++;
  33. }
  34. // Split node
  35. void splitNode(int item, int *pval, int pos, struct btreeNode *node,
  36. struct btreeNode *child, struct btreeNode **newNode) {
  37. int median, j;
  38. if (pos > MIN)
  39. median = MIN + 1;
  40. else
  41. median = MIN;
  42. *newNode = (struct btreeNode *)malloc(sizeof(struct btreeNode));
  43. j = median + 1;
  44. while (j <= MAX) {
  45. (*newNode)->item[j - median] = node->item[j];
  46. (*newNode)->link[j - median] = node->link[j];
  47. j++;
  48. }
  49. node->count = median;
  50. (*newNode)->count = MAX - median;
  51. if (pos <= MIN) {
  52. insertValue(item, pos, node, child);
  53. } else {
  54. insertValue(item, pos - median, *newNode, child);
  55. }
  56. *pval = node->item[node->count];
  57. (*newNode)->link[0] = node->link[node->count];
  58. node->count--;
  59. }
  60. // Set the value of node
  61. int setNodeValue(int item, int *pval,
  62. struct btreeNode *node, struct btreeNode **child) {
  63. int pos;
  64. if (!node) {
  65. *pval = item;
  66. *child = NULL;
  67. return 1;
  68. }
  69. if (item < node->item[1]) {
  70. pos = 0;
  71. } else {
  72. for (pos = node->count;
  73. (item < node->item[pos] && pos > 1); pos--)
  74. ;
  75. if (item == node->item[pos]) {
  76. printf("Duplicates not allowed\n");
  77. return 0;
  78. }
  79. }
  80. if (setNodeValue(item, pval, node->link[pos], child)) {
  81. if (node->count < MAX) {
  82. insertValue(*pval, pos, node, *child);
  83. } else {
  84. splitNode(*pval, pval, pos, node, *child, child);
  85. return 1;
  86. }
  87. }
  88. return 0;
  89. }
  90. // Insert the value
  91. void insertion(int item) {
  92. int flag, i;
  93. struct btreeNode *child;
  94. flag = setNodeValue(item, &i, root, &child);
  95. if (flag)
  96. root = createNode(i, child);
  97. }
  98. // Copy the successor
  99. void copySuccessor(struct btreeNode *myNode, int pos) {
  100. struct btreeNode *dummy;
  101. dummy = myNode->link[pos];
  102. for (; dummy->link[0] != NULL;)
  103. dummy = dummy->link[0];
  104. myNode->item[pos] = dummy->item[1];
  105. }
  106. // Do rightshift
  107. void rightShift(struct btreeNode *myNode, int pos) {
  108. struct btreeNode *x = myNode->link[pos];
  109. int j = x->count;
  110. while (j > 0) {
  111. x->item[j + 1] = x->item[j];
  112. x->link[j + 1] = x->link[j];
  113. }
  114. x->item[1] = myNode->item[pos];
  115. x->link[1] = x->link[0];
  116. x->count++;
  117. x = myNode->link[pos - 1];
  118. myNode->item[pos] = x->item[x->count];
  119. myNode->link[pos] = x->link[x->count];
  120. x->count--;
  121. return;
  122. }
  123. // Do leftshift
  124. void leftShift(struct btreeNode *myNode, int pos) {
  125. int j = 1;
  126. struct btreeNode *x = myNode->link[pos - 1];
  127. x->count++;
  128. x->item[x->count] = myNode->item[pos];
  129. x->link[x->count] = myNode->link[pos]->link[0];
  130. x = myNode->link[pos];
  131. myNode->item[pos] = x->item[1];
  132. x->link[0] = x->link[1];
  133. x->count--;
  134. while (j <= x->count) {
  135. x->item[j] = x->item[j + 1];
  136. x->link[j] = x->link[j + 1];
  137. j++;
  138. }
  139. return;
  140. }
  141. // Merge the nodes
  142. void mergeNodes(struct btreeNode *myNode, int pos) {
  143. int j = 1;
  144. struct btreeNode *x1 = myNode->link[pos], *x2 = myNode->link[pos - 1];
  145. x2->count++;
  146. x2->item[x2->count] = myNode->item[pos];
  147. x2->link[x2->count] = myNode->link[0];
  148. while (j <= x1->count) {
  149. x2->count++;
  150. x2->item[x2->count] = x1->item[j];
  151. x2->link[x2->count] = x1->link[j];
  152. j++;
  153. }
  154. j = pos;
  155. while (j < myNode->count) {
  156. myNode->item[j] = myNode->item[j + 1];
  157. myNode->link[j] = myNode->link[j + 1];
  158. j++;
  159. }
  160. myNode->count--;
  161. free(x1);
  162. }
  163. // Adjust the node
  164. void adjustNode(struct btreeNode *myNode, int pos) {
  165. if (!pos) {
  166. if (myNode->link[1]->count > MIN) {
  167. leftShift(myNode, 1);
  168. } else {
  169. mergeNodes(myNode, 1);
  170. }
  171. } else {
  172. if (myNode->count != pos) {
  173. if (myNode->link[pos - 1]->count > MIN) {
  174. rightShift(myNode, pos);
  175. } else {
  176. if (myNode->link[pos + 1]->count > MIN) {
  177. leftShift(myNode, pos + 1);
  178. } else {
  179. mergeNodes(myNode, pos);
  180. }
  181. }
  182. } else {
  183. if (myNode->link[pos - 1]->count > MIN)
  184. rightShift(myNode, pos);
  185. else
  186. mergeNodes(myNode, pos);
  187. }
  188. }
  189. }
  190. // Traverse the tree
  191. void traversal(struct btreeNode *myNode) {
  192. int i;
  193. if (myNode) {
  194. for (i = 0; i < myNode->count; i++) {
  195. traversal(myNode->link[i]);
  196. printf("%d ", myNode->item[i + 1]);
  197. }
  198. traversal(myNode->link[i]);
  199. }
  200. }
  201. int main() {
  202. int item, ch;
  203. insertion(8);
  204. insertion(9);
  205. insertion(10);
  206. insertion(11);
  207. insertion(15);
  208. insertion(16);
  209. insertion(17);
  210. insertion(18);
  211. insertion(20);
  212. insertion(23);
  213. traversal(root);
  214. }
// Inserting a key on a B-tree in C++

#include <iostream>
using namespace std;

class Node {
  int *keys;
  int t;
  Node **C;
  int n;
  bool leaf;

   public:
  Node(int _t, bool _leaf);

  void insertNonFull(int k);
  void splitChild(int i, Node *y);
  void traverse();

  friend class BTree;
};

class BTree {
  Node *root;
  int t;

   public:
  BTree(int _t) {
    root = NULL;
    t = _t;
  }

  void traverse() {
    if (root != NULL)
      root->traverse();
  }

  void insert(int k);
};

Node::Node(int t1, bool leaf1) {
  t = t1;
  leaf = leaf1;

  keys = new int[2 * t - 1];
  C = new Node *[2 * t];

  n = 0;
}

// Traverse the nodes
void Node::traverse() {
  int i;
  for (i = 0; i < n; i++) {
    if (leaf == false)
      C[i]->traverse();
    cout << " " << keys[i];
  }

  if (leaf == false)
    C[i]->traverse();
}

// Insert the node
void BTree::insert(int k) {
  if (root == NULL) {
    root = new Node(t, true);
    root->keys[0] = k;
    root->n = 1;
  } else {
    if (root->n == 2 * t - 1) {
      Node *s = new Node(t, false);

      s->C[0] = root;

      s->splitChild(0, root);

      int i = 0;
      if (s->keys[0] < k)
        i++;
      s->C[i]->insertNonFull(k);

      root = s;
    } else
      root->insertNonFull(k);
  }
}

// Insert non full condition
void Node::insertNonFull(int k) {
  int i = n - 1;

  if (leaf == true) {
    while (i >= 0 && keys[i] > k) {
      keys[i + 1] = keys[i];
      i--;
    }

    keys[i + 1] = k;
    n = n + 1;
  } else {
    while (i >= 0 && keys[i] > k)
      i--;

    if (C[i + 1]->n == 2 * t - 1) {
      splitChild(i + 1, C[i + 1]);

      if (keys[i + 1] < k)
        i++;
    }
    C[i + 1]->insertNonFull(k);
  }
}

// split the child
void Node::splitChild(int i, Node *y) {
  Node *z = new Node(y->t, y->leaf);
  z->n = t - 1;

  for (int j = 0; j < t - 1; j++)
    z->keys[j] = y->keys[j + t];

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

  y->n = t - 1;
  for (int j = n; j >= i + 1; j--)
    C[j + 1] = C[j];

  C[i + 1] = z;

  for (int j = n - 1; j >= i; j--)
    keys[j + 1] = keys[j];

  keys[i] = y->keys[t - 1];
  n = n + 1;
}

int main() {
  BTree t(3);
  t.insert(8);
  t.insert(9);
  t.insert(10);
  t.insert(11);
  t.insert(15);
  t.insert(16);
  t.insert(17);
  t.insert(18);
  t.insert(20);
  t.insert(23);

  cout << "The B-tree is: ";
  t.traverse();
}