原文: https://www.programiz.com/dsa/deletion-from-a-b-plus-tree

在本教程中,您将了解有关 B+ 树的删除操作。 此外,您还将找到从 C,C++ ,Java 和 Python 中的 B+ 树中删除元素的工作示例。

删除 B+ 树上的元素包括三个主要事件:搜索要删除的键所在的节点,删除键并按需平衡树。 下溢是节点中的键数量少于其应容纳的最小键数量的情况。


删除操作

在执行以下步骤之前,必须了解有关度为m的 B+ 树的这些事实。

  1. 一个节点最多可以有m个子节点。 (即 3)
  2. 一个节点最多可以包含m - 1个键。 (即 2)
  3. 一个节点至少应具有⌈m/2⌉个子节点。 (即 2)
  4. 一个节点(根节点除外)应至少包含⌈m/2⌉ - 1键。 (即 1)

删除键时,我们还必须照顾内部节点(即索引)中存在的键,因为这些值在 B+ 树中是多余的。 搜索要删除的键,然后按照以下步骤操作。

情况一

要删除的键仅存在于叶节点上,而不存在于索引(或内部节点)中。 有两种情况:

  1. 节点中的键数目超过最小数目。 只需删除键。
    从 B  树中删除 - 图1
    从 B 树删除 40

  2. 节点中有确切的最小键数。 删除键并从直接同级中借用键。 将同级节点的中间键添加到父级。
    从 B  树中删除 - 图2
    从 B 树中删除 5

情况二

内部节点中也存在要删除的键。 然后,我们也必须从内部节点中删除它们。 对于这种情况,有以下几种情况。

  1. 如果节点中的键数量超过最小数量,则只需从叶节点删除键,并从内部节点删除键即可。
    用顺序后继填充内部节点中的空白区域。
    从 B  树中删除 - 图3
    从 B 树删除 45

  2. 如果节点中的键数量确切最小,则删除该键并从其直接同级(通过父级)借用一个键。
    使用借来的键填充在索引(内部节点)中创建的空白空间。
    从 B  树中删除 - 图4
    从 B 树中删除 35

  3. 这种情况与情况 II(1)相似,但是在此处,直接父节点上方会生成空白空间。
    删除键后,将空白空间与其同级合并。
    用顺序后继填充祖父节点中的空白区域。
    从 B  树中删除 - 图5
    从 B 树中删除 25

情况三

在这种情况下,树的高度会缩小。 这有点复杂。从下面的树中删除 55 会导致这种情况。 在下面的插图中可以理解。

从 B  树中删除 - 图6

从 B 树中删除 55


Python,Java 和 C/C++ 示例

  1. # B+ tee in python
  2. import math
  3. # Node creation
  4. class Node:
  5. def __init__(self, order):
  6. self.order = order
  7. self.values = []
  8. self.keys = []
  9. self.nextKey = None
  10. self.parent = None
  11. self.check_leaf = False
  12. # Insert at the leaf
  13. def insert_at_leaf(self, leaf, value, key):
  14. if (self.values):
  15. temp1 = self.values
  16. for i in range(len(temp1)):
  17. if (value == temp1[i]):
  18. self.keys[i].append(key)
  19. break
  20. elif (value < temp1[i]):
  21. self.values = self.values[:i] + [value] + self.values[i:]
  22. self.keys = self.keys[:i] + [[key]] + self.keys[i:]
  23. break
  24. elif (i + 1 == len(temp1)):
  25. self.values.append(value)
  26. self.keys.append([key])
  27. break
  28. else:
  29. self.values = [value]
  30. self.keys = [[key]]
  31. # B plus tree
  32. class BplusTree:
  33. def __init__(self, order):
  34. self.root = Node(order)
  35. self.root.check_leaf = True
  36. # Insert operation
  37. def insert(self, value, key):
  38. value = str(value)
  39. old_node = self.search(value)
  40. old_node.insert_at_leaf(old_node, value, key)
  41. if (len(old_node.values) == old_node.order):
  42. node1 = Node(old_node.order)
  43. node1.check_leaf = True
  44. node1.parent = old_node.parent
  45. mid = int(math.ceil(old_node.order / 2)) - 1
  46. node1.values = old_node.values[mid + 1:]
  47. node1.keys = old_node.keys[mid + 1:]
  48. node1.nextKey = old_node.nextKey
  49. old_node.values = old_node.values[:mid + 1]
  50. old_node.keys = old_node.keys[:mid + 1]
  51. old_node.nextKey = node1
  52. self.insert_in_parent(old_node, node1.values[0], node1)
  53. # Search operation for different operations
  54. def search(self, value):
  55. current_node = self.root
  56. while(current_node.check_leaf == False):
  57. temp2 = current_node.values
  58. for i in range(len(temp2)):
  59. if (value == temp2[i]):
  60. current_node = current_node.keys[i + 1]
  61. break
  62. elif (value < temp2[i]):
  63. current_node = current_node.keys[i]
  64. break
  65. elif (i + 1 == len(current_node.values)):
  66. current_node = current_node.keys[i + 1]
  67. break
  68. return current_node
  69. # Find the node
  70. def find(self, value, key):
  71. l = self.search(value)
  72. for i, item in enumerate(l.values):
  73. if item == value:
  74. if key in l.keys[i]:
  75. return True
  76. else:
  77. return False
  78. return False
  79. # Inserting at the parent
  80. def insert_in_parent(self, n, value, ndash):
  81. if (self.root == n):
  82. rootNode = Node(n.order)
  83. rootNode.values = [value]
  84. rootNode.keys = [n, ndash]
  85. self.root = rootNode
  86. n.parent = rootNode
  87. ndash.parent = rootNode
  88. return
  89. parentNode = n.parent
  90. temp3 = parentNode.keys
  91. for i in range(len(temp3)):
  92. if (temp3[i] == n):
  93. parentNode.values = parentNode.values[:i] + \
  94. [value] + parentNode.values[i:]
  95. parentNode.keys = parentNode.keys[:i +
  96. 1] + [ndash] + parentNode.keys[i + 1:]
  97. if (len(parentNode.keys) > parentNode.order):
  98. parentdash = Node(parentNode.order)
  99. parentdash.parent = parentNode.parent
  100. mid = int(math.ceil(parentNode.order / 2)) - 1
  101. parentdash.values = parentNode.values[mid + 1:]
  102. parentdash.keys = parentNode.keys[mid + 1:]
  103. value_ = parentNode.values[mid]
  104. if (mid == 0):
  105. parentNode.values = parentNode.values[:mid + 1]
  106. else:
  107. parentNode.values = parentNode.values[:mid]
  108. parentNode.keys = parentNode.keys[:mid + 1]
  109. for j in parentNode.keys:
  110. j.parent = parentNode
  111. for j in parentdash.keys:
  112. j.parent = parentdash
  113. self.insert_in_parent(parentNode, value_, parentdash)
  114. # Delete a node
  115. def delete(self, value, key):
  116. node_ = self.search(value)
  117. temp = 0
  118. for i, item in enumerate(node_.values):
  119. if item == value:
  120. temp = 1
  121. if key in node_.keys[i]:
  122. if len(node_.keys[i]) > 1:
  123. node_.keys[i].pop(node_.keys[i].index(key))
  124. elif node_ == self.root:
  125. node_.values.pop(i)
  126. node_.keys.pop(i)
  127. else:
  128. node_.keys[i].pop(node_.keys[i].index(key))
  129. del node_.keys[i]
  130. node_.values.pop(node_.values.index(value))
  131. self.deleteEntry(node_, value, key)
  132. else:
  133. print("Value not in Key")
  134. return
  135. if temp == 0:
  136. print("Value not in Tree")
  137. return
  138. # Delete an entry
  139. def deleteEntry(self, node_, value, key):
  140. if not node_.check_leaf:
  141. for i, item in enumerate(node_.keys):
  142. if item == key:
  143. node_.keys.pop(i)
  144. break
  145. for i, item in enumerate(node_.values):
  146. if item == value:
  147. node_.values.pop(i)
  148. break
  149. if self.root == node_ and len(node_.keys) == 1:
  150. self.root = node_.keys[0]
  151. node_.keys[0].parent = None
  152. del node_
  153. return
  154. elif (len(node_.keys) < int(math.ceil(node_.order / 2)) and node_.check_leaf == False) or (len(node_.values) < int(math.ceil((node_.order - 1) / 2)) and node_.check_leaf == True):
  155. is_predecessor = 0
  156. parentNode = node_.parent
  157. PrevNode = -1
  158. NextNode = -1
  159. PrevK = -1
  160. PostK = -1
  161. for i, item in enumerate(parentNode.keys):
  162. if item == node_:
  163. if i > 0:
  164. PrevNode = parentNode.keys[i - 1]
  165. PrevK = parentNode.values[i - 1]
  166. if i < len(parentNode.keys) - 1:
  167. NextNode = parentNode.keys[i + 1]
  168. PostK = parentNode.values[i]
  169. if PrevNode == -1:
  170. ndash = NextNode
  171. value_ = PostK
  172. elif NextNode == -1:
  173. is_predecessor = 1
  174. ndash = PrevNode
  175. value_ = PrevK
  176. else:
  177. if len(node_.values) + len(NextNode.values) < node_.order:
  178. ndash = NextNode
  179. value_ = PostK
  180. else:
  181. is_predecessor = 1
  182. ndash = PrevNode
  183. value_ = PrevK
  184. if len(node_.values) + len(ndash.values) < node_.order:
  185. if is_predecessor == 0:
  186. node_, ndash = ndash, node_
  187. ndash.keys += node_.keys
  188. if not node_.check_leaf:
  189. ndash.values.append(value_)
  190. else:
  191. ndash.nextKey = node_.nextKey
  192. ndash.values += node_.values
  193. if not ndash.check_leaf:
  194. for j in ndash.keys:
  195. j.parent = ndash
  196. self.deleteEntry(node_.parent, value_, node_)
  197. del node_
  198. else:
  199. if is_predecessor == 1:
  200. if not node_.check_leaf:
  201. ndashpm = ndash.keys.pop(-1)
  202. ndashkm_1 = ndash.values.pop(-1)
  203. node_.keys = [ndashpm] + node_.keys
  204. node_.values = [value_] + node_.values
  205. parentNode = node_.parent
  206. for i, item in enumerate(parentNode.values):
  207. if item == value_:
  208. p.values[i] = ndashkm_1
  209. break
  210. else:
  211. ndashpm = ndash.keys.pop(-1)
  212. ndashkm = ndash.values.pop(-1)
  213. node_.keys = [ndashpm] + node_.keys
  214. node_.values = [ndashkm] + node_.values
  215. parentNode = node_.parent
  216. for i, item in enumerate(p.values):
  217. if item == value_:
  218. parentNode.values[i] = ndashkm
  219. break
  220. else:
  221. if not node_.check_leaf:
  222. ndashp0 = ndash.keys.pop(0)
  223. ndashk0 = ndash.values.pop(0)
  224. node_.keys = node_.keys + [ndashp0]
  225. node_.values = node_.values + [value_]
  226. parentNode = node_.parent
  227. for i, item in enumerate(parentNode.values):
  228. if item == value_:
  229. parentNode.values[i] = ndashk0
  230. break
  231. else:
  232. ndashp0 = ndash.keys.pop(0)
  233. ndashk0 = ndash.values.pop(0)
  234. node_.keys = node_.keys + [ndashp0]
  235. node_.values = node_.values + [ndashk0]
  236. parentNode = node_.parent
  237. for i, item in enumerate(parentNode.values):
  238. if item == value_:
  239. parentNode.values[i] = ndash.values[0]
  240. break
  241. if not ndash.check_leaf:
  242. for j in ndash.keys:
  243. j.parent = ndash
  244. if not node_.check_leaf:
  245. for j in node_.keys:
  246. j.parent = node_
  247. if not parentNode.check_leaf:
  248. for j in parentNode.keys:
  249. j.parent = parentNode
  250. # Print the tree
  251. def printTree(tree):
  252. lst = [tree.root]
  253. level = [0]
  254. leaf = None
  255. flag = 0
  256. lev_leaf = 0
  257. node1 = Node(str(level[0]) + str(tree.root.values))
  258. while (len(lst) != 0):
  259. x = lst.pop(0)
  260. lev = level.pop(0)
  261. if (x.check_leaf == False):
  262. for i, item in enumerate(x.keys):
  263. print(item.values)
  264. else:
  265. for i, item in enumerate(x.keys):
  266. print(item.values)
  267. if (flag == 0):
  268. lev_leaf = lev
  269. leaf = x
  270. flag = 1
  271. record_len = 3
  272. bplustree = BplusTree(record_len)
  273. bplustree.insert('5', '33')
  274. bplustree.insert('15', '21')
  275. bplustree.insert('25', '31')
  276. bplustree.insert('35', '41')
  277. bplustree.insert('45', '10')
  278. printTree(bplustree)
  279. if(bplustree.find('5', '34')):
  280. print("Found")
  281. else:
  282. print("Not found")
  1. // Searching on a B+ tree in Java
  2. import java.util.*;
  3. public class BPlusTree {
  4. int m;
  5. InternalNode root;
  6. LeafNode firstLeaf;
  7. // Binary search program
  8. private int binarySearch(DictionaryPair[] dps, int numPairs, int t) {
  9. Comparator<DictionaryPair> c = new Comparator<DictionaryPair>() {
  10. @Override
  11. public int compare(DictionaryPair o1, DictionaryPair o2) {
  12. Integer a = Integer.valueOf(o1.key);
  13. Integer b = Integer.valueOf(o2.key);
  14. return a.compareTo(b);
  15. }
  16. };
  17. return Arrays.binarySearch(dps, 0, numPairs, new DictionaryPair(t, 0), c);
  18. }
  19. // Find the leaf node
  20. private LeafNode findLeafNode(int key) {
  21. Integer[] keys = this.root.keys;
  22. int i;
  23. for (i = 0; i < this.root.degree - 1; i++) {
  24. if (key < keys[i]) {
  25. break;
  26. }
  27. }
  28. Node child = this.root.childPointers[i];
  29. if (child instanceof LeafNode) {
  30. return (LeafNode) child;
  31. } else {
  32. return findLeafNode((InternalNode) child, key);
  33. }
  34. }
  35. // Find the leaf node
  36. private LeafNode findLeafNode(InternalNode node, int key) {
  37. Integer[] keys = node.keys;
  38. int i;
  39. for (i = 0; i < node.degree - 1; i++) {
  40. if (key < keys[i]) {
  41. break;
  42. }
  43. }
  44. Node childNode = node.childPointers[i];
  45. if (childNode instanceof LeafNode) {
  46. return (LeafNode) childNode;
  47. } else {
  48. return findLeafNode((InternalNode) node.childPointers[i], key);
  49. }
  50. }
  51. // Finding the index of the pointer
  52. private int findIndexOfPointer(Node[] pointers, LeafNode node) {
  53. int i;
  54. for (i = 0; i < pointers.length; i++) {
  55. if (pointers[i] == node) {
  56. break;
  57. }
  58. }
  59. return i;
  60. }
  61. // Get the mid point
  62. private int getMidpoint() {
  63. return (int) Math.ceil((this.m + 1) / 2.0) - 1;
  64. }
  65. // Balance the tree
  66. private void handleDeficiency(InternalNode in) {
  67. InternalNode sibling;
  68. InternalNode parent = in.parent;
  69. if (this.root == in) {
  70. for (int i = 0; i < in.childPointers.length; i++) {
  71. if (in.childPointers[i] != null) {
  72. if (in.childPointers[i] instanceof InternalNode) {
  73. this.root = (InternalNode) in.childPointers[i];
  74. this.root.parent = null;
  75. } else if (in.childPointers[i] instanceof LeafNode) {
  76. this.root = null;
  77. }
  78. }
  79. }
  80. }
  81. else if (in.leftSibling != null && in.leftSibling.isLendable()) {
  82. sibling = in.leftSibling;
  83. } else if (in.rightSibling != null && in.rightSibling.isLendable()) {
  84. sibling = in.rightSibling;
  85. int borrowedKey = sibling.keys[0];
  86. Node pointer = sibling.childPointers[0];
  87. in.keys[in.degree - 1] = parent.keys[0];
  88. in.childPointers[in.degree] = pointer;
  89. parent.keys[0] = borrowedKey;
  90. sibling.removePointer(0);
  91. Arrays.sort(sibling.keys);
  92. sibling.removePointer(0);
  93. shiftDown(in.childPointers, 1);
  94. } else if (in.leftSibling != null && in.leftSibling.isMergeable()) {
  95. } else if (in.rightSibling != null && in.rightSibling.isMergeable()) {
  96. sibling = in.rightSibling;
  97. sibling.keys[sibling.degree - 1] = parent.keys[parent.degree - 2];
  98. Arrays.sort(sibling.keys, 0, sibling.degree);
  99. parent.keys[parent.degree - 2] = null;
  100. for (int i = 0; i < in.childPointers.length; i++) {
  101. if (in.childPointers[i] != null) {
  102. sibling.prependChildPointer(in.childPointers[i]);
  103. in.childPointers[i].parent = sibling;
  104. in.removePointer(i);
  105. }
  106. }
  107. parent.removePointer(in);
  108. sibling.leftSibling = in.leftSibling;
  109. }
  110. if (parent != null && parent.isDeficient()) {
  111. handleDeficiency(parent);
  112. }
  113. }
  114. private boolean isEmpty() {
  115. return firstLeaf == null;
  116. }
  117. private int linearNullSearch(DictionaryPair[] dps) {
  118. for (int i = 0; i < dps.length; i++) {
  119. if (dps[i] == null) {
  120. return i;
  121. }
  122. }
  123. return -1;
  124. }
  125. private int linearNullSearch(Node[] pointers) {
  126. for (int i = 0; i < pointers.length; i++) {
  127. if (pointers[i] == null) {
  128. return i;
  129. }
  130. }
  131. return -1;
  132. }
  133. private void shiftDown(Node[] pointers, int amount) {
  134. Node[] newPointers = new Node[this.m + 1];
  135. for (int i = amount; i < pointers.length; i++) {
  136. newPointers[i - amount] = pointers[i];
  137. }
  138. pointers = newPointers;
  139. }
  140. private void sortDictionary(DictionaryPair[] dictionary) {
  141. Arrays.sort(dictionary, new Comparator<DictionaryPair>() {
  142. @Override
  143. public int compare(DictionaryPair o1, DictionaryPair o2) {
  144. if (o1 == null && o2 == null) {
  145. return 0;
  146. }
  147. if (o1 == null) {
  148. return 1;
  149. }
  150. if (o2 == null) {
  151. return -1;
  152. }
  153. return o1.compareTo(o2);
  154. }
  155. });
  156. }
  157. private Node[] splitChildPointers(InternalNode in, int split) {
  158. Node[] pointers = in.childPointers;
  159. Node[] halfPointers = new Node[this.m + 1];
  160. for (int i = split + 1; i < pointers.length; i++) {
  161. halfPointers[i - split - 1] = pointers[i];
  162. in.removePointer(i);
  163. }
  164. return halfPointers;
  165. }
  166. private DictionaryPair[] splitDictionary(LeafNode ln, int split) {
  167. DictionaryPair[] dictionary = ln.dictionary;
  168. DictionaryPair[] halfDict = new DictionaryPair[this.m];
  169. for (int i = split; i < dictionary.length; i++) {
  170. halfDict[i - split] = dictionary[i];
  171. ln.delete(i);
  172. }
  173. return halfDict;
  174. }
  175. private void splitInternalNode(InternalNode in) {
  176. InternalNode parent = in.parent;
  177. int midpoint = getMidpoint();
  178. int newParentKey = in.keys[midpoint];
  179. Integer[] halfKeys = splitKeys(in.keys, midpoint);
  180. Node[] halfPointers = splitChildPointers(in, midpoint);
  181. in.degree = linearNullSearch(in.childPointers);
  182. InternalNode sibling = new InternalNode(this.m, halfKeys, halfPointers);
  183. for (Node pointer : halfPointers) {
  184. if (pointer != null) {
  185. pointer.parent = sibling;
  186. }
  187. }
  188. sibling.rightSibling = in.rightSibling;
  189. if (sibling.rightSibling != null) {
  190. sibling.rightSibling.leftSibling = sibling;
  191. }
  192. in.rightSibling = sibling;
  193. sibling.leftSibling = in;
  194. if (parent == null) {
  195. Integer[] keys = new Integer[this.m];
  196. keys[0] = newParentKey;
  197. InternalNode newRoot = new InternalNode(this.m, keys);
  198. newRoot.appendChildPointer(in);
  199. newRoot.appendChildPointer(sibling);
  200. this.root = newRoot;
  201. in.parent = newRoot;
  202. sibling.parent = newRoot;
  203. } else {
  204. parent.keys[parent.degree - 1] = newParentKey;
  205. Arrays.sort(parent.keys, 0, parent.degree);
  206. int pointerIndex = parent.findIndexOfPointer(in) + 1;
  207. parent.insertChildPointer(sibling, pointerIndex);
  208. sibling.parent = parent;
  209. }
  210. }
  211. private Integer[] splitKeys(Integer[] keys, int split) {
  212. Integer[] halfKeys = new Integer[this.m];
  213. keys[split] = null;
  214. for (int i = split + 1; i < keys.length; i++) {
  215. halfKeys[i - split - 1] = keys[i];
  216. keys[i] = null;
  217. }
  218. return halfKeys;
  219. }
  220. public void insert(int key, double value) {
  221. if (isEmpty()) {
  222. LeafNode ln = new LeafNode(this.m, new DictionaryPair(key, value));
  223. this.firstLeaf = ln;
  224. } else {
  225. LeafNode ln = (this.root == null) ? this.firstLeaf : findLeafNode(key);
  226. if (!ln.insert(new DictionaryPair(key, value))) {
  227. ln.dictionary[ln.numPairs] = new DictionaryPair(key, value);
  228. ln.numPairs++;
  229. sortDictionary(ln.dictionary);
  230. int midpoint = getMidpoint();
  231. DictionaryPair[] halfDict = splitDictionary(ln, midpoint);
  232. if (ln.parent == null) {
  233. Integer[] parent_keys = new Integer[this.m];
  234. parent_keys[0] = halfDict[0].key;
  235. InternalNode parent = new InternalNode(this.m, parent_keys);
  236. ln.parent = parent;
  237. parent.appendChildPointer(ln);
  238. } else {
  239. int newParentKey = halfDict[0].key;
  240. ln.parent.keys[ln.parent.degree - 1] = newParentKey;
  241. Arrays.sort(ln.parent.keys, 0, ln.parent.degree);
  242. }
  243. LeafNode newLeafNode = new LeafNode(this.m, halfDict, ln.parent);
  244. int pointerIndex = ln.parent.findIndexOfPointer(ln) + 1;
  245. ln.parent.insertChildPointer(newLeafNode, pointerIndex);
  246. newLeafNode.rightSibling = ln.rightSibling;
  247. if (newLeafNode.rightSibling != null) {
  248. newLeafNode.rightSibling.leftSibling = newLeafNode;
  249. }
  250. ln.rightSibling = newLeafNode;
  251. newLeafNode.leftSibling = ln;
  252. if (this.root == null) {
  253. this.root = ln.parent;
  254. } else {
  255. InternalNode in = ln.parent;
  256. while (in != null) {
  257. if (in.isOverfull()) {
  258. splitInternalNode(in);
  259. } else {
  260. break;
  261. }
  262. in = in.parent;
  263. }
  264. }
  265. }
  266. }
  267. }
  268. public Double search(int key) {
  269. if (isEmpty()) {
  270. return null;
  271. }
  272. LeafNode ln = (this.root == null) ? this.firstLeaf : findLeafNode(key);
  273. DictionaryPair[] dps = ln.dictionary;
  274. int index = binarySearch(dps, ln.numPairs, key);
  275. if (index < 0) {
  276. return null;
  277. } else {
  278. return dps[index].value;
  279. }
  280. }
  281. public ArrayList<Double> search(int lowerBound, int upperBound) {
  282. ArrayList<Double> values = new ArrayList<Double>();
  283. LeafNode currNode = this.firstLeaf;
  284. while (currNode != null) {
  285. DictionaryPair dps[] = currNode.dictionary;
  286. for (DictionaryPair dp : dps) {
  287. if (dp == null) {
  288. break;
  289. }
  290. if (lowerBound <= dp.key && dp.key <= upperBound) {
  291. values.add(dp.value);
  292. }
  293. }
  294. currNode = currNode.rightSibling;
  295. }
  296. return values;
  297. }
  298. public BPlusTree(int m) {
  299. this.m = m;
  300. this.root = null;
  301. }
  302. public class Node {
  303. InternalNode parent;
  304. }
  305. private class InternalNode extends Node {
  306. int maxDegree;
  307. int minDegree;
  308. int degree;
  309. InternalNode leftSibling;
  310. InternalNode rightSibling;
  311. Integer[] keys;
  312. Node[] childPointers;
  313. private void appendChildPointer(Node pointer) {
  314. this.childPointers[degree] = pointer;
  315. this.degree++;
  316. }
  317. private int findIndexOfPointer(Node pointer) {
  318. for (int i = 0; i < childPointers.length; i++) {
  319. if (childPointers[i] == pointer) {
  320. return i;
  321. }
  322. }
  323. return -1;
  324. }
  325. private void insertChildPointer(Node pointer, int index) {
  326. for (int i = degree - 1; i >= index; i--) {
  327. childPointers[i + 1] = childPointers[i];
  328. }
  329. this.childPointers[index] = pointer;
  330. this.degree++;
  331. }
  332. private boolean isDeficient() {
  333. return this.degree < this.minDegree;
  334. }
  335. private boolean isLendable() {
  336. return this.degree > this.minDegree;
  337. }
  338. private boolean isMergeable() {
  339. return this.degree == this.minDegree;
  340. }
  341. private boolean isOverfull() {
  342. return this.degree == maxDegree + 1;
  343. }
  344. private void prependChildPointer(Node pointer) {
  345. for (int i = degree - 1; i >= 0; i--) {
  346. childPointers[i + 1] = childPointers[i];
  347. }
  348. this.childPointers[0] = pointer;
  349. this.degree++;
  350. }
  351. private void removeKey(int index) {
  352. this.keys[index] = null;
  353. }
  354. private void removePointer(int index) {
  355. this.childPointers[index] = null;
  356. this.degree--;
  357. }
  358. private void removePointer(Node pointer) {
  359. for (int i = 0; i < childPointers.length; i++) {
  360. if (childPointers[i] == pointer) {
  361. this.childPointers[i] = null;
  362. }
  363. }
  364. this.degree--;
  365. }
  366. private InternalNode(int m, Integer[] keys) {
  367. this.maxDegree = m;
  368. this.minDegree = (int) Math.ceil(m / 2.0);
  369. this.degree = 0;
  370. this.keys = keys;
  371. this.childPointers = new Node[this.maxDegree + 1];
  372. }
  373. private InternalNode(int m, Integer[] keys, Node[] pointers) {
  374. this.maxDegree = m;
  375. this.minDegree = (int) Math.ceil(m / 2.0);
  376. this.degree = linearNullSearch(pointers);
  377. this.keys = keys;
  378. this.childPointers = pointers;
  379. }
  380. }
  381. public class LeafNode extends Node {
  382. int maxNumPairs;
  383. int minNumPairs;
  384. int numPairs;
  385. LeafNode leftSibling;
  386. LeafNode rightSibling;
  387. DictionaryPair[] dictionary;
  388. public void delete(int index) {
  389. this.dictionary[index] = null;
  390. numPairs--;
  391. }
  392. public boolean insert(DictionaryPair dp) {
  393. if (this.isFull()) {
  394. return false;
  395. } else {
  396. this.dictionary[numPairs] = dp;
  397. numPairs++;
  398. Arrays.sort(this.dictionary, 0, numPairs);
  399. return true;
  400. }
  401. }
  402. public boolean isDeficient() {
  403. return numPairs < minNumPairs;
  404. }
  405. public boolean isFull() {
  406. return numPairs == maxNumPairs;
  407. }
  408. public boolean isLendable() {
  409. return numPairs > minNumPairs;
  410. }
  411. public boolean isMergeable() {
  412. return numPairs == minNumPairs;
  413. }
  414. public LeafNode(int m, DictionaryPair dp) {
  415. this.maxNumPairs = m - 1;
  416. this.minNumPairs = (int) (Math.ceil(m / 2) - 1);
  417. this.dictionary = new DictionaryPair[m];
  418. this.numPairs = 0;
  419. this.insert(dp);
  420. }
  421. public LeafNode(int m, DictionaryPair[] dps, InternalNode parent) {
  422. this.maxNumPairs = m - 1;
  423. this.minNumPairs = (int) (Math.ceil(m / 2) - 1);
  424. this.dictionary = dps;
  425. this.numPairs = linearNullSearch(dps);
  426. this.parent = parent;
  427. }
  428. }
  429. public class DictionaryPair implements Comparable<DictionaryPair> {
  430. int key;
  431. double value;
  432. public DictionaryPair(int key, double value) {
  433. this.key = key;
  434. this.value = value;
  435. }
  436. public int compareTo(DictionaryPair o) {
  437. if (key == o.key) {
  438. return 0;
  439. } else if (key > o.key) {
  440. return 1;
  441. } else {
  442. return -1;
  443. }
  444. }
  445. }
  446. public static void main(String[] args) {
  447. BPlusTree bpt = null;
  448. bpt = new BPlusTree(3);
  449. bpt.insert(5, 33);
  450. bpt.insert(15, 21);
  451. bpt.insert(25, 31);
  452. bpt.insert(35, 41);
  453. bpt.insert(45, 10);
  454. if (bpt.search(15) != null) {
  455. System.out.println("Found");
  456. } else {
  457. System.out.println("Not Found");
  458. }
  459. ;
  460. }
  461. }
// Searching on a B+ Tree in C

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Default order
#define ORDER 3

typedef struct record {
  int value;
} record;

// Node
typedef struct node {
  void **pointers;
  int *keys;
  struct node *parent;
  bool is_leaf;
  int num_keys;
  struct node *next;
} node;

int order = ORDER;
node *queue = NULL;
bool verbose_output = false;

// Enqueue
void enqueue(node *new_node);

// Dequeue
node *dequeue(void);
int height(node *const root);
int pathToLeaves(node *const root, node *child);
void printLeaves(node *const root);
void printTree(node *const root);
void findAndPrint(node *const root, int key, bool verbose);
void findAndPrintRange(node *const root, int range1, int range2, bool verbose);
int findRange(node *const root, int key_start, int key_end, bool verbose,
        int returned_keys[], void *returned_pointers[]);
node *findLeaf(node *const root, int key, bool verbose);
record *find(node *root, int key, bool verbose, node **leaf_out);
int cut(int length);

record *makeRecord(int value);
node *makeNode(void);
node *makeLeaf(void);
int getLeftIndex(node *parent, node *left);
node *insertIntoLeaf(node *leaf, int key, record *pointer);
node *insertIntoLeafAfterSplitting(node *root, node *leaf, int key,
                   record *pointer);
node *insertIntoNode(node *root, node *parent,
           int left_index, int key, node *right);
node *insertIntoNodeAfterSplitting(node *root, node *parent,
                   int left_index,
                   int key, node *right);
node *insertIntoParent(node *root, node *left, int key, node *right);
node *insertIntoNewRoot(node *left, int key, node *right);
node *startNewTree(int key, record *pointer);
node *insert(node *root, int key, int value);

// Enqueue
void enqueue(node *new_node) {
  node *c;
  if (queue == NULL) {
    queue = new_node;
    queue->next = NULL;
  } else {
    c = queue;
    while (c->next != NULL) {
      c = c->next;
    }
    c->next = new_node;
    new_node->next = NULL;
  }
}

// Dequeue
node *dequeue(void) {
  node *n = queue;
  queue = queue->next;
  n->next = NULL;
  return n;
}

// Print the leaves
void printLeaves(node *const root) {
  if (root == NULL) {
    printf("Empty tree.\n");
    return;
  }
  int i;
  node *c = root;
  while (!c->is_leaf)
    c = c->pointers[0];
  while (true) {
    for (i = 0; i < c->num_keys; i++) {
      if (verbose_output)
        printf("%p ", c->pointers[i]);
      printf("%d ", c->keys[i]);
    }
    if (verbose_output)
      printf("%p ", c->pointers[order - 1]);
    if (c->pointers[order - 1] != NULL) {
      printf(" | ");
      c = c->pointers[order - 1];
    } else
      break;
  }
  printf("\n");
}

// Calculate height
int height(node *const root) {
  int h = 0;
  node *c = root;
  while (!c->is_leaf) {
    c = c->pointers[0];
    h++;
  }
  return h;
}

// Get path to root
int pathToLeaves(node *const root, node *child) {
  int length = 0;
  node *c = child;
  while (c != root) {
    c = c->parent;
    length++;
  }
  return length;
}

// Print the tree
void printTree(node *const root) {
  node *n = NULL;
  int i = 0;
  int rank = 0;
  int new_rank = 0;

  if (root == NULL) {
    printf("Empty tree.\n");
    return;
  }
  queue = NULL;
  enqueue(root);
  while (queue != NULL) {
    n = dequeue();
    if (n->parent != NULL && n == n->parent->pointers[0]) {
      new_rank = pathToLeaves(root, n);
      if (new_rank != rank) {
        rank = new_rank;
        printf("\n");
      }
    }
    if (verbose_output)
      printf("(%p)", n);
    for (i = 0; i < n->num_keys; i++) {
      if (verbose_output)
        printf("%p ", n->pointers[i]);
      printf("%d ", n->keys[i]);
    }
    if (!n->is_leaf)
      for (i = 0; i <= n->num_keys; i++)
        enqueue(n->pointers[i]);
    if (verbose_output) {
      if (n->is_leaf)
        printf("%p ", n->pointers[order - 1]);
      else
        printf("%p ", n->pointers[n->num_keys]);
    }
    printf("| ");
  }
  printf("\n");
}

// Find the node and print it
void findAndPrint(node *const root, int key, bool verbose) {
  node *leaf = NULL;
  record *r = find(root, key, verbose, NULL);
  if (r == NULL)
    printf("Record not found under key %d.\n", key);
  else
    printf("Record at %p -- key %d, value %d.\n",
         r, key, r->value);
}

// Find and print the range
void findAndPrintRange(node *const root, int key_start, int key_end,
             bool verbose) {
  int i;
  int array_size = key_end - key_start + 1;
  int returned_keys[array_size];
  void *returned_pointers[array_size];
  int num_found = findRange(root, key_start, key_end, verbose,
                returned_keys, returned_pointers);
  if (!num_found)
    printf("None found.\n");
  else {
    for (i = 0; i < num_found; i++)
      printf("Key: %d   Location: %p  Value: %d\n",
           returned_keys[i],
           returned_pointers[i],
           ((record *)
            returned_pointers[i])
             ->value);
  }
}

// Find the range
int findRange(node *const root, int key_start, int key_end, bool verbose,
        int returned_keys[], void *returned_pointers[]) {
  int i, num_found;
  num_found = 0;
  node *n = findLeaf(root, key_start, verbose);
  if (n == NULL)
    return 0;
  for (i = 0; i < n->num_keys && n->keys[i] < key_start; i++)
    ;
  if (i == n->num_keys)
    return 0;
  while (n != NULL) {
    for (; i < n->num_keys && n->keys[i] <= key_end; i++) {
      returned_keys[num_found] = n->keys[i];
      returned_pointers[num_found] = n->pointers[i];
      num_found++;
    }
    n = n->pointers[order - 1];
    i = 0;
  }
  return num_found;
}

// Find the leaf
node *findLeaf(node *const root, int key, bool verbose) {
  if (root == NULL) {
    if (verbose)
      printf("Empty tree.\n");
    return root;
  }
  int i = 0;
  node *c = root;
  while (!c->is_leaf) {
    if (verbose) {
      printf("[");
      for (i = 0; i < c->num_keys - 1; i++)
        printf("%d ", c->keys[i]);
      printf("%d] ", c->keys[i]);
    }
    i = 0;
    while (i < c->num_keys) {
      if (key >= c->keys[i])
        i++;
      else
        break;
    }
    if (verbose)
      printf("%d ->\n", i);
    c = (node *)c->pointers[i];
  }
  if (verbose) {
    printf("Leaf [");
    for (i = 0; i < c->num_keys - 1; i++)
      printf("%d ", c->keys[i]);
    printf("%d] ->\n", c->keys[i]);
  }
  return c;
}

record *find(node *root, int key, bool verbose, node **leaf_out) {
  if (root == NULL) {
    if (leaf_out != NULL) {
      *leaf_out = NULL;
    }
    return NULL;
  }

  int i = 0;
  node *leaf = NULL;

  leaf = findLeaf(root, key, verbose);

  for (i = 0; i < leaf->num_keys; i++)
    if (leaf->keys[i] == key)
      break;
  if (leaf_out != NULL) {
    *leaf_out = leaf;
  }
  if (i == leaf->num_keys)
    return NULL;
  else
    return (record *)leaf->pointers[i];
}

int cut(int length) {
  if (length % 2 == 0)
    return length / 2;
  else
    return length / 2 + 1;
}

record *makeRecord(int value) {
  record *new_record = (record *)malloc(sizeof(record));
  if (new_record == NULL) {
    perror("Record creation.");
    exit(EXIT_FAILURE);
  } else {
    new_record->value = value;
  }
  return new_record;
}

node *makeNode(void) {
  node *new_node;
  new_node = malloc(sizeof(node));
  if (new_node == NULL) {
    perror("Node creation.");
    exit(EXIT_FAILURE);
  }
  new_node->keys = malloc((order - 1) * sizeof(int));
  if (new_node->keys == NULL) {
    perror("New node keys array.");
    exit(EXIT_FAILURE);
  }
  new_node->pointers = malloc(order * sizeof(void *));
  if (new_node->pointers == NULL) {
    perror("New node pointers array.");
    exit(EXIT_FAILURE);
  }
  new_node->is_leaf = false;
  new_node->num_keys = 0;
  new_node->parent = NULL;
  new_node->next = NULL;
  return new_node;
}

node *makeLeaf(void) {
  node *leaf = makeNode();
  leaf->is_leaf = true;
  return leaf;
}

int getLeftIndex(node *parent, node *left) {
  int left_index = 0;
  while (left_index <= parent->num_keys &&
       parent->pointers[left_index] != left)
    left_index++;
  return left_index;
}

node *insertIntoLeaf(node *leaf, int key, record *pointer) {
  int i, insertion_point;

  insertion_point = 0;
  while (insertion_point < leaf->num_keys && leaf->keys[insertion_point] < key)
    insertion_point++;

  for (i = leaf->num_keys; i > insertion_point; i--) {
    leaf->keys[i] = leaf->keys[i - 1];
    leaf->pointers[i] = leaf->pointers[i - 1];
  }
  leaf->keys[insertion_point] = key;
  leaf->pointers[insertion_point] = pointer;
  leaf->num_keys++;
  return leaf;
}

node *insertIntoLeafAfterSplitting(node *root, node *leaf, int key, record *pointer) {
  node *new_leaf;
  int *temp_keys;
  void **temp_pointers;
  int insertion_index, split, new_key, i, j;

  new_leaf = makeLeaf();

  temp_keys = malloc(order * sizeof(int));
  if (temp_keys == NULL) {
    perror("Temporary keys array.");
    exit(EXIT_FAILURE);
  }

  temp_pointers = malloc(order * sizeof(void *));
  if (temp_pointers == NULL) {
    perror("Temporary pointers array.");
    exit(EXIT_FAILURE);
  }

  insertion_index = 0;
  while (insertion_index < order - 1 && leaf->keys[insertion_index] < key)
    insertion_index++;

  for (i = 0, j = 0; i < leaf->num_keys; i++, j++) {
    if (j == insertion_index)
      j++;
    temp_keys[j] = leaf->keys[i];
    temp_pointers[j] = leaf->pointers[i];
  }

  temp_keys[insertion_index] = key;
  temp_pointers[insertion_index] = pointer;

  leaf->num_keys = 0;

  split = cut(order - 1);

  for (i = 0; i < split; i++) {
    leaf->pointers[i] = temp_pointers[i];
    leaf->keys[i] = temp_keys[i];
    leaf->num_keys++;
  }

  for (i = split, j = 0; i < order; i++, j++) {
    new_leaf->pointers[j] = temp_pointers[i];
    new_leaf->keys[j] = temp_keys[i];
    new_leaf->num_keys++;
  }

  free(temp_pointers);
  free(temp_keys);

  new_leaf->pointers[order - 1] = leaf->pointers[order - 1];
  leaf->pointers[order - 1] = new_leaf;

  for (i = leaf->num_keys; i < order - 1; i++)
    leaf->pointers[i] = NULL;
  for (i = new_leaf->num_keys; i < order - 1; i++)
    new_leaf->pointers[i] = NULL;

  new_leaf->parent = leaf->parent;
  new_key = new_leaf->keys[0];

  return insertIntoParent(root, leaf, new_key, new_leaf);
}

node *insertIntoNode(node *root, node *n,
           int left_index, int key, node *right) {
  int i;

  for (i = n->num_keys; i > left_index; i--) {
    n->pointers[i + 1] = n->pointers[i];
    n->keys[i] = n->keys[i - 1];
  }
  n->pointers[left_index + 1] = right;
  n->keys[left_index] = key;
  n->num_keys++;
  return root;
}

node *insertIntoNodeAfterSplitting(node *root, node *old_node, int left_index,
                   int key, node *right) {
  int i, j, split, k_prime;
  node *new_node, *child;
  int *temp_keys;
  node **temp_pointers;

  temp_pointers = malloc((order + 1) * sizeof(node *));
  if (temp_pointers == NULL) {
    exit(EXIT_FAILURE);
  }
  temp_keys = malloc(order * sizeof(int));
  if (temp_keys == NULL) {
    exit(EXIT_FAILURE);
  }

  for (i = 0, j = 0; i < old_node->num_keys + 1; i++, j++) {
    if (j == left_index + 1)
      j++;
    temp_pointers[j] = old_node->pointers[i];
  }

  for (i = 0, j = 0; i < old_node->num_keys; i++, j++) {
    if (j == left_index)
      j++;
    temp_keys[j] = old_node->keys[i];
  }

  temp_pointers[left_index + 1] = right;
  temp_keys[left_index] = key;

  split = cut(order);
  new_node = makeNode();
  old_node->num_keys = 0;
  for (i = 0; i < split - 1; i++) {
    old_node->pointers[i] = temp_pointers[i];
    old_node->keys[i] = temp_keys[i];
    old_node->num_keys++;
  }
  old_node->pointers[i] = temp_pointers[i];
  k_prime = temp_keys[split - 1];
  for (++i, j = 0; i < order; i++, j++) {
    new_node->pointers[j] = temp_pointers[i];
    new_node->keys[j] = temp_keys[i];
    new_node->num_keys++;
  }
  new_node->pointers[j] = temp_pointers[i];
  free(temp_pointers);
  free(temp_keys);
  new_node->parent = old_node->parent;
  for (i = 0; i <= new_node->num_keys; i++) {
    child = new_node->pointers[i];
    child->parent = new_node;
  }

  return insertIntoParent(root, old_node, k_prime, new_node);
}

node *insertIntoParent(node *root, node *left, int key, node *right) {
  int left_index;
  node *parent;

  parent = left->parent;

  if (parent == NULL)
    return insertIntoNewRoot(left, key, right);

  left_index = getLeftIndex(parent, left);

  if (parent->num_keys < order - 1)
    return insertIntoNode(root, parent, left_index, key, right);

  return insertIntoNodeAfterSplitting(root, parent, left_index, key, right);
}

node *insertIntoNewRoot(node *left, int key, node *right) {
  node *root = makeNode();
  root->keys[0] = key;
  root->pointers[0] = left;
  root->pointers[1] = right;
  root->num_keys++;
  root->parent = NULL;
  left->parent = root;
  right->parent = root;
  return root;
}

node *startNewTree(int key, record *pointer) {
  node *root = makeLeaf();
  root->keys[0] = key;
  root->pointers[0] = pointer;
  root->pointers[order - 1] = NULL;
  root->parent = NULL;
  root->num_keys++;
  return root;
}

node *insert(node *root, int key, int value) {
  record *record_pointer = NULL;
  node *leaf = NULL;

  record_pointer = find(root, key, false, NULL);
  if (record_pointer != NULL) {
    record_pointer->value = value;
    return root;
  }

  record_pointer = makeRecord(value);

  if (root == NULL)
    return startNewTree(key, record_pointer);

  leaf = findLeaf(root, key, false);

  if (leaf->num_keys < order - 1) {
    leaf = insertIntoLeaf(leaf, key, record_pointer);
    return root;
  }

  return insertIntoLeafAfterSplitting(root, leaf, key, record_pointer);
}

int main() {
  node *root;
  char instruction;

  root = NULL;

  root = insert(root, 5, 33);
  root = insert(root, 15, 21);
  root = insert(root, 25, 31);
  root = insert(root, 35, 41);
  root = insert(root, 45, 10);

  printTree(root);

  findAndPrint(root, 15, instruction = 'a');
}
// Searching on a B+ tree in C++

#include <climits>
#include <fstream>
#include <iostream>
#include <sstream>
using namespace std;
int MAX = 3;

// BP node
class Node {
  bool IS_LEAF;
  int *key, size;
  Node **ptr;
  friend class BPTree;

   public:
  Node();
};

// BP tree
class BPTree {
  Node *root;
  void insertInternal(int, Node *, Node *);
  Node *findParent(Node *, Node *);

   public:
  BPTree();
  void search(int);
  void insert(int);
  void display(Node *);
  Node *getRoot();
};

Node::Node() {
  key = new int[MAX];
  ptr = new Node *[MAX + 1];
}

BPTree::BPTree() {
  root = NULL;
}

// Search operation
void BPTree::search(int x) {
  if (root == NULL) {
    cout << "Tree is empty\n";
  } else {
    Node *cursor = root;
    while (cursor->IS_LEAF == false) {
      for (int i = 0; i < cursor->size; i++) {
        if (x < cursor->key[i]) {
          cursor = cursor->ptr[i];
          break;
        }
        if (i == cursor->size - 1) {
          cursor = cursor->ptr[i + 1];
          break;
        }
      }
    }
    for (int i = 0; i < cursor->size; i++) {
      if (cursor->key[i] == x) {
        cout << "Found\n";
        return;
      }
    }
    cout << "Not found\n";
  }
}

// Insert Operation
void BPTree::insert(int x) {
  if (root == NULL) {
    root = new Node;
    root->key[0] = x;
    root->IS_LEAF = true;
    root->size = 1;
  } else {
    Node *cursor = root;
    Node *parent;
    while (cursor->IS_LEAF == false) {
      parent = cursor;
      for (int i = 0; i < cursor->size; i++) {
        if (x < cursor->key[i]) {
          cursor = cursor->ptr[i];
          break;
        }
        if (i == cursor->size - 1) {
          cursor = cursor->ptr[i + 1];
          break;
        }
      }
    }
    if (cursor->size < MAX) {
      int i = 0;
      while (x > cursor->key[i] && i < cursor->size)
        i++;
      for (int j = cursor->size; j > i; j--) {
        cursor->key[j] = cursor->key[j - 1];
      }
      cursor->key[i] = x;
      cursor->size++;
      cursor->ptr[cursor->size] = cursor->ptr[cursor->size - 1];
      cursor->ptr[cursor->size - 1] = NULL;
    } else {
      Node *newLeaf = new Node;
      int virtualNode[MAX + 1];
      for (int i = 0; i < MAX; i++) {
        virtualNode[i] = cursor->key[i];
      }
      int i = 0, j;
      while (x > virtualNode[i] && i < MAX)
        i++;
      for (int j = MAX + 1; j > i; j--) {
        virtualNode[j] = virtualNode[j - 1];
      }
      virtualNode[i] = x;
      newLeaf->IS_LEAF = true;
      cursor->size = (MAX + 1) / 2;
      newLeaf->size = MAX + 1 - (MAX + 1) / 2;
      cursor->ptr[cursor->size] = newLeaf;
      newLeaf->ptr[newLeaf->size] = cursor->ptr[MAX];
      cursor->ptr[MAX] = NULL;
      for (i = 0; i < cursor->size; i++) {
        cursor->key[i] = virtualNode[i];
      }
      for (i = 0, j = cursor->size; i < newLeaf->size; i++, j++) {
        newLeaf->key[i] = virtualNode[j];
      }
      if (cursor == root) {
        Node *newRoot = new Node;
        newRoot->key[0] = newLeaf->key[0];
        newRoot->ptr[0] = cursor;
        newRoot->ptr[1] = newLeaf;
        newRoot->IS_LEAF = false;
        newRoot->size = 1;
        root = newRoot;
      } else {
        insertInternal(newLeaf->key[0], parent, newLeaf);
      }
    }
  }
}

// Insert Operation
void BPTree::insertInternal(int x, Node *cursor, Node *child) {
  if (cursor->size < MAX) {
    int i = 0;
    while (x > cursor->key[i] && i < cursor->size)
      i++;
    for (int j = cursor->size; j > i; j--) {
      cursor->key[j] = cursor->key[j - 1];
    }
    for (int j = cursor->size + 1; j > i + 1; j--) {
      cursor->ptr[j] = cursor->ptr[j - 1];
    }
    cursor->key[i] = x;
    cursor->size++;
    cursor->ptr[i + 1] = child;
  } else {
    Node *newInternal = new Node;
    int virtualKey[MAX + 1];
    Node *virtualPtr[MAX + 2];
    for (int i = 0; i < MAX; i++) {
      virtualKey[i] = cursor->key[i];
    }
    for (int i = 0; i < MAX + 1; i++) {
      virtualPtr[i] = cursor->ptr[i];
    }
    int i = 0, j;
    while (x > virtualKey[i] && i < MAX)
      i++;
    for (int j = MAX + 1; j > i; j--) {
      virtualKey[j] = virtualKey[j - 1];
    }
    virtualKey[i] = x;
    for (int j = MAX + 2; j > i + 1; j--) {
      virtualPtr[j] = virtualPtr[j - 1];
    }
    virtualPtr[i + 1] = child;
    newInternal->IS_LEAF = false;
    cursor->size = (MAX + 1) / 2;
    newInternal->size = MAX - (MAX + 1) / 2;
    for (i = 0, j = cursor->size + 1; i < newInternal->size; i++, j++) {
      newInternal->key[i] = virtualKey[j];
    }
    for (i = 0, j = cursor->size + 1; i < newInternal->size + 1; i++, j++) {
      newInternal->ptr[i] = virtualPtr[j];
    }
    if (cursor == root) {
      Node *newRoot = new Node;
      newRoot->key[0] = cursor->key[cursor->size];
      newRoot->ptr[0] = cursor;
      newRoot->ptr[1] = newInternal;
      newRoot->IS_LEAF = false;
      newRoot->size = 1;
      root = newRoot;
    } else {
      insertInternal(cursor->key[cursor->size], findParent(root, cursor), newInternal);
    }
  }
}

// Find the parent
Node *BPTree::findParent(Node *cursor, Node *child) {
  Node *parent;
  if (cursor->IS_LEAF || (cursor->ptr[0])->IS_LEAF) {
    return NULL;
  }
  for (int i = 0; i < cursor->size + 1; i++) {
    if (cursor->ptr[i] == child) {
      parent = cursor;
      return parent;
    } else {
      parent = findParent(cursor->ptr[i], child);
      if (parent != NULL)
        return parent;
    }
  }
  return parent;
}

// Print the tree
void BPTree::display(Node *cursor) {
  if (cursor != NULL) {
    for (int i = 0; i < cursor->size; i++) {
      cout << cursor->key[i] << " ";
    }
    cout << "\n";
    if (cursor->IS_LEAF != true) {
      for (int i = 0; i < cursor->size + 1; i++) {
        display(cursor->ptr[i]);
      }
    }
  }
}

// Get the root
Node *BPTree::getRoot() {
  return root;
}

int main() {
  BPTree node;
  node.insert(5);
  node.insert(15);
  node.insert(25);
  node.insert(35);
  node.insert(45);
  node.insert(55);
  node.insert(40);
  node.insert(30);
  node.insert(20);
  node.display(node.getRoot());

  node.search(15);
}

删除复杂度

时间复杂度:Θ(t log_t(n))

复杂度由Θ(log_t(n))决定。