main.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. // C++ Program to Implement B-Tree
  2. #include <iostream>
  3. using namespace std;
  4. // class for the node present in a B-Tree
  5. template <typename T, int ORDER>
  6. class BTreeNode {
  7. public:
  8. // Array of keys
  9. T keys[ORDER - 1];
  10. // Array of child pointers
  11. BTreeNode* children[ORDER];
  12. // Current number of keys
  13. int n;
  14. // True if leaf node, false otherwise
  15. bool leaf;
  16. BTreeNode(bool isLeaf = true) : n(0), leaf(isLeaf) {
  17. for (int i = 0; i < ORDER; i++)
  18. children[i] = nullptr;
  19. }
  20. };
  21. // class for B-Tree
  22. template <typename T, int ORDER>
  23. class BTree {
  24. private:
  25. BTreeNode<T, ORDER>* root; // Pointer to root node
  26. // Function to split a full child node
  27. void splitChild(BTreeNode<T, ORDER>* x, int i) {
  28. BTreeNode<T, ORDER>* y = x->children[i];
  29. BTreeNode<T, ORDER>* z = new BTreeNode<T, ORDER>(y->leaf);
  30. z->n = ORDER / 2 - 1;
  31. for (int j = 0; j < ORDER / 2 - 1; j++)
  32. z->keys[j] = y->keys[j + ORDER / 2];
  33. if (!y->leaf) {
  34. for (int j = 0; j < ORDER / 2; j++)
  35. z->children[j] = y->children[j + ORDER / 2];
  36. }
  37. y->n = ORDER / 2 - 1;
  38. for (int j = x->n; j >= i + 1; j--)
  39. x->children[j + 1] = x->children[j];
  40. x->children[i + 1] = z;
  41. for (int j = x->n - 1; j >= i; j--)
  42. x->keys[j + 1] = x->keys[j];
  43. x->keys[i] = y->keys[ORDER / 2 - 1];
  44. x->n = x->n + 1;
  45. }
  46. // Function to insert a key in a non-full node
  47. void insertNonFull(BTreeNode<T, ORDER>* x, T k) {
  48. int i = x->n - 1;
  49. if (x->leaf) {
  50. while (i >= 0 && k < x->keys[i]) {
  51. x->keys[i + 1] = x->keys[i];
  52. i--;
  53. }
  54. x->keys[i + 1] = k;
  55. x->n = x->n + 1;
  56. } else {
  57. while (i >= 0 && k < x->keys[i])
  58. i--;
  59. i++;
  60. if (x->children[i]->n == ORDER - 1) {
  61. splitChild(x, i);
  62. if (k > x->keys[i])
  63. i++;
  64. }
  65. insertNonFull(x->children[i], k);
  66. }
  67. }
  68. // Function to traverse the tree
  69. void traverse(BTreeNode<T, ORDER>* x) {
  70. int i;
  71. for (i = 0; i < x->n; i++) {
  72. if (!x->leaf)
  73. traverse(x->children[i]);
  74. cout << " " << x->keys[i];
  75. }
  76. if (!x->leaf)
  77. traverse(x->children[i]);
  78. }
  79. // Function to search a key in the tree
  80. BTreeNode<T, ORDER>* search(BTreeNode<T, ORDER>* x, T k) {
  81. int i = 0;
  82. while (i < x->n && k > x->keys[i])
  83. i++;
  84. if (i < x->n && k == x->keys[i])
  85. return x;
  86. if (x->leaf)
  87. return nullptr;
  88. return search(x->children[i], k);
  89. }
  90. // Function to find the predecessor
  91. T getPredecessor(BTreeNode<T, ORDER>* node, int idx) {
  92. BTreeNode<T, ORDER>* current = node->children[idx];
  93. while (!current->leaf)
  94. current = current->children[current->n];
  95. return current->keys[current->n - 1];
  96. }
  97. // Function to find the successor
  98. T getSuccessor(BTreeNode<T, ORDER>* node, int idx) {
  99. BTreeNode<T, ORDER>* current = node->children[idx + 1];
  100. while (!current->leaf)
  101. current = current->children[0];
  102. return current->keys[0];
  103. }
  104. // Function to fill child node
  105. void fill(BTreeNode<T, ORDER>* node, int idx) {
  106. if (idx != 0 && node->children[idx - 1]->n >= ORDER / 2)
  107. borrowFromPrev(node, idx);
  108. else if (idx != node->n && node->children[idx + 1]->n >= ORDER / 2)
  109. borrowFromNext(node, idx);
  110. else {
  111. if (idx != node->n)
  112. merge(node, idx);
  113. else
  114. merge(node, idx - 1);
  115. }
  116. }
  117. // Function to borrow from previous sibling
  118. void borrowFromPrev(BTreeNode<T, ORDER>* node, int idx) {
  119. BTreeNode<T, ORDER>* child = node->children[idx];
  120. BTreeNode<T, ORDER>* sibling = node->children[idx - 1];
  121. for (int i = child->n - 1; i >= 0; --i)
  122. child->keys[i + 1] = child->keys[i];
  123. if (!child->leaf) {
  124. for (int i = child->n; i >= 0; --i)
  125. child->children[i + 1] = child->children[i];
  126. }
  127. child->keys[0] = node->keys[idx - 1];
  128. if (!child->leaf)
  129. child->children[0] = sibling->children[sibling->n];
  130. node->keys[idx - 1] = sibling->keys[sibling->n - 1];
  131. child->n += 1;
  132. sibling->n -= 1;
  133. }
  134. // Function to borrow from next sibling
  135. void borrowFromNext(BTreeNode<T, ORDER>* node, int idx) {
  136. BTreeNode<T, ORDER>* child = node->children[idx];
  137. BTreeNode<T, ORDER>* sibling = node->children[idx + 1];
  138. child->keys[child->n] = node->keys[idx];
  139. if (!child->leaf)
  140. child->children[child->n + 1] = sibling->children[0];
  141. node->keys[idx] = sibling->keys[0];
  142. for (int i = 1; i < sibling->n; ++i)
  143. sibling->keys[i - 1] = sibling->keys[i];
  144. if (!sibling->leaf) {
  145. for (int i = 1; i <= sibling->n; ++i)
  146. sibling->children[i - 1] = sibling->children[i];
  147. }
  148. child->n += 1;
  149. sibling->n -= 1;
  150. }
  151. // Function to merge two nodes
  152. void merge(BTreeNode<T, ORDER>* node, int idx) {
  153. BTreeNode<T, ORDER>* child = node->children[idx];
  154. BTreeNode<T, ORDER>* sibling = node->children[idx + 1];
  155. child->keys[ORDER / 2 - 1] = node->keys[idx];
  156. for (int i = 0; i < sibling->n; ++i)
  157. child->keys[i + ORDER / 2] = sibling->keys[i];
  158. if (!child->leaf) {
  159. for (int i = 0; i <= sibling->n; ++i)
  160. child->children[i + ORDER / 2] = sibling->children[i];
  161. }
  162. for (int i = idx + 1; i < node->n; ++i)
  163. node->keys[i - 1] = node->keys[i];
  164. for (int i = idx + 2; i <= node->n; ++i)
  165. node->children[i - 1] = node->children[i];
  166. child->n += sibling->n + 1;
  167. node->n--;
  168. delete sibling;
  169. }
  170. // Function to remove a key from a non-leaf node
  171. void removeFromNonLeaf(BTreeNode<T, ORDER>* node, int idx) {
  172. T k = node->keys[idx];
  173. if (node->children[idx]->n >= ORDER / 2) {
  174. T pred = getPredecessor(node, idx);
  175. node->keys[idx] = pred;
  176. remove(node->children[idx], pred);
  177. } else if (node->children[idx + 1]->n >= ORDER / 2) {
  178. T succ = getSuccessor(node, idx);
  179. node->keys[idx] = succ;
  180. remove(node->children[idx + 1], succ);
  181. } else {
  182. merge(node, idx);
  183. remove(node->children[idx], k);
  184. }
  185. }
  186. // Function to remove a key from a leaf node
  187. void removeFromLeaf(BTreeNode<T, ORDER>* node, int idx) {
  188. for (int i = idx + 1; i < node->n; ++i)
  189. node->keys[i - 1] = node->keys[i];
  190. node->n--;
  191. }
  192. // Function to remove a key from the tree
  193. void remove(BTreeNode<T, ORDER>* node, T k) {
  194. int idx = 0;
  195. while (idx < node->n && node->keys[idx] < k)
  196. ++idx;
  197. if (idx < node->n && node->keys[idx] == k) {
  198. if (node->leaf)
  199. removeFromLeaf(node, idx);
  200. else
  201. removeFromNonLeaf(node, idx);
  202. } else {
  203. if (node->leaf) {
  204. cout << "The key " << k << " is not present in the tree\n";
  205. return;
  206. }
  207. bool flag = ((idx == node->n) ? true : false);
  208. if (node->children[idx]->n < ORDER / 2)
  209. fill(node, idx);
  210. if (flag && idx > node->n)
  211. remove(node->children[idx - 1], k);
  212. else
  213. remove(node->children[idx], k);
  214. }
  215. }
  216. public:
  217. BTree() { root = new BTreeNode<T, ORDER>(true); }
  218. // Function to insert a key in the tree
  219. void insert(T k) {
  220. if (root->n == ORDER - 1) {
  221. BTreeNode<T, ORDER>* s = new BTreeNode<T, ORDER>(false);
  222. s->children[0] = root;
  223. root = s;
  224. splitChild(s, 0);
  225. insertNonFull(s, k);
  226. } else
  227. insertNonFull(root, k);
  228. }
  229. // Function to traverse the tree
  230. void traverse() {
  231. if (root != nullptr)
  232. traverse(root);
  233. }
  234. // Function to search a key in the tree
  235. BTreeNode<T, ORDER>* search(T k) {
  236. return (root == nullptr) ? nullptr : search(root, k);
  237. }
  238. // Function to remove a key from the tree
  239. void remove(T k) {
  240. if (!root) {
  241. cout << "The tree is empty\n";
  242. return;
  243. }
  244. remove(root, k);
  245. if (root->n == 0) {
  246. BTreeNode<T, ORDER>* tmp = root;
  247. if (root->leaf)
  248. root = nullptr;
  249. else
  250. root = root->children[0];
  251. delete tmp;
  252. }
  253. }
  254. };
  255. int main() {
  256. BTree<int, 3> t;
  257. t.insert(10);
  258. t.insert(20);
  259. t.insert(5);
  260. t.insert(6);
  261. t.insert(12);
  262. t.insert(30);
  263. t.insert(7);
  264. t.insert(17);
  265. cout << "Traversal of the constructed tree is: ";
  266. t.traverse();
  267. cout << endl;
  268. int k = 6;
  269. (t.search(k) != nullptr) ? cout << k << " is found" << endl
  270. : cout << k << " is not found" << endl;
  271. k = 15;
  272. (t.search(k) != nullptr) ? cout << k << " is found" << endl
  273. : cout << k << " is not found" << endl;
  274. t.remove(6);
  275. cout << "Traversal of the tree after removing 6: ";
  276. t.traverse();
  277. cout << endl;
  278. t.remove(13);
  279. cout << "Traversal of the tree after removing 13: ";
  280. t.traverse();
  281. cout << endl;
  282. return 0;
  283. }