| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 |
- // C++ Program to Implement B-Tree
- #include <iostream>
- using namespace std;
- // class for the node present in a B-Tree
- template <typename T, int ORDER>
- class BTreeNode {
- public:
- // Array of keys
- T keys[ORDER - 1];
- // Array of child pointers
- BTreeNode* children[ORDER];
- // Current number of keys
- int n;
- // True if leaf node, false otherwise
- bool leaf;
- BTreeNode(bool isLeaf = true) : n(0), leaf(isLeaf) {
- for (int i = 0; i < ORDER; i++)
- children[i] = nullptr;
- }
- };
- // class for B-Tree
- template <typename T, int ORDER>
- class BTree {
- private:
- BTreeNode<T, ORDER>* root; // Pointer to root node
- // Function to split a full child node
- void splitChild(BTreeNode<T, ORDER>* x, int i) {
- BTreeNode<T, ORDER>* y = x->children[i];
- BTreeNode<T, ORDER>* z = new BTreeNode<T, ORDER>(y->leaf);
- z->n = ORDER / 2 - 1;
- for (int j = 0; j < ORDER / 2 - 1; j++)
- z->keys[j] = y->keys[j + ORDER / 2];
- if (!y->leaf) {
- for (int j = 0; j < ORDER / 2; j++)
- z->children[j] = y->children[j + ORDER / 2];
- }
- y->n = ORDER / 2 - 1;
- for (int j = x->n; j >= i + 1; j--)
- x->children[j + 1] = x->children[j];
- x->children[i + 1] = z;
- for (int j = x->n - 1; j >= i; j--)
- x->keys[j + 1] = x->keys[j];
- x->keys[i] = y->keys[ORDER / 2 - 1];
- x->n = x->n + 1;
- }
- // Function to insert a key in a non-full node
- void insertNonFull(BTreeNode<T, ORDER>* x, T k) {
- int i = x->n - 1;
- if (x->leaf) {
- while (i >= 0 && k < x->keys[i]) {
- x->keys[i + 1] = x->keys[i];
- i--;
- }
- x->keys[i + 1] = k;
- x->n = x->n + 1;
- } else {
- while (i >= 0 && k < x->keys[i])
- i--;
- i++;
- if (x->children[i]->n == ORDER - 1) {
- splitChild(x, i);
- if (k > x->keys[i])
- i++;
- }
- insertNonFull(x->children[i], k);
- }
- }
- // Function to traverse the tree
- void traverse(BTreeNode<T, ORDER>* x) {
- int i;
- for (i = 0; i < x->n; i++) {
- if (!x->leaf)
- traverse(x->children[i]);
- cout << " " << x->keys[i];
- }
- if (!x->leaf)
- traverse(x->children[i]);
- }
- // Function to search a key in the tree
- BTreeNode<T, ORDER>* search(BTreeNode<T, ORDER>* x, T k) {
- int i = 0;
- while (i < x->n && k > x->keys[i])
- i++;
- if (i < x->n && k == x->keys[i])
- return x;
- if (x->leaf)
- return nullptr;
- return search(x->children[i], k);
- }
- // Function to find the predecessor
- T getPredecessor(BTreeNode<T, ORDER>* node, int idx) {
- BTreeNode<T, ORDER>* current = node->children[idx];
- while (!current->leaf)
- current = current->children[current->n];
- return current->keys[current->n - 1];
- }
- // Function to find the successor
- T getSuccessor(BTreeNode<T, ORDER>* node, int idx) {
- BTreeNode<T, ORDER>* current = node->children[idx + 1];
- while (!current->leaf)
- current = current->children[0];
- return current->keys[0];
- }
- // Function to fill child node
- void fill(BTreeNode<T, ORDER>* node, int idx) {
- if (idx != 0 && node->children[idx - 1]->n >= ORDER / 2)
- borrowFromPrev(node, idx);
- else if (idx != node->n && node->children[idx + 1]->n >= ORDER / 2)
- borrowFromNext(node, idx);
- else {
- if (idx != node->n)
- merge(node, idx);
- else
- merge(node, idx - 1);
- }
- }
- // Function to borrow from previous sibling
- void borrowFromPrev(BTreeNode<T, ORDER>* node, int idx) {
- BTreeNode<T, ORDER>* child = node->children[idx];
- BTreeNode<T, ORDER>* sibling = node->children[idx - 1];
- for (int i = child->n - 1; i >= 0; --i)
- child->keys[i + 1] = child->keys[i];
- if (!child->leaf) {
- for (int i = child->n; i >= 0; --i)
- child->children[i + 1] = child->children[i];
- }
- child->keys[0] = node->keys[idx - 1];
- if (!child->leaf)
- child->children[0] = sibling->children[sibling->n];
- node->keys[idx - 1] = sibling->keys[sibling->n - 1];
- child->n += 1;
- sibling->n -= 1;
- }
- // Function to borrow from next sibling
- void borrowFromNext(BTreeNode<T, ORDER>* node, int idx) {
- BTreeNode<T, ORDER>* child = node->children[idx];
- BTreeNode<T, ORDER>* sibling = node->children[idx + 1];
- child->keys[child->n] = node->keys[idx];
- if (!child->leaf)
- child->children[child->n + 1] = sibling->children[0];
- node->keys[idx] = sibling->keys[0];
- for (int i = 1; i < sibling->n; ++i)
- sibling->keys[i - 1] = sibling->keys[i];
- if (!sibling->leaf) {
- for (int i = 1; i <= sibling->n; ++i)
- sibling->children[i - 1] = sibling->children[i];
- }
- child->n += 1;
- sibling->n -= 1;
- }
- // Function to merge two nodes
- void merge(BTreeNode<T, ORDER>* node, int idx) {
- BTreeNode<T, ORDER>* child = node->children[idx];
- BTreeNode<T, ORDER>* sibling = node->children[idx + 1];
- child->keys[ORDER / 2 - 1] = node->keys[idx];
- for (int i = 0; i < sibling->n; ++i)
- child->keys[i + ORDER / 2] = sibling->keys[i];
- if (!child->leaf) {
- for (int i = 0; i <= sibling->n; ++i)
- child->children[i + ORDER / 2] = sibling->children[i];
- }
- for (int i = idx + 1; i < node->n; ++i)
- node->keys[i - 1] = node->keys[i];
- for (int i = idx + 2; i <= node->n; ++i)
- node->children[i - 1] = node->children[i];
- child->n += sibling->n + 1;
- node->n--;
- delete sibling;
- }
- // Function to remove a key from a non-leaf node
- void removeFromNonLeaf(BTreeNode<T, ORDER>* node, int idx) {
- T k = node->keys[idx];
- if (node->children[idx]->n >= ORDER / 2) {
- T pred = getPredecessor(node, idx);
- node->keys[idx] = pred;
- remove(node->children[idx], pred);
- } else if (node->children[idx + 1]->n >= ORDER / 2) {
- T succ = getSuccessor(node, idx);
- node->keys[idx] = succ;
- remove(node->children[idx + 1], succ);
- } else {
- merge(node, idx);
- remove(node->children[idx], k);
- }
- }
- // Function to remove a key from a leaf node
- void removeFromLeaf(BTreeNode<T, ORDER>* node, int idx) {
- for (int i = idx + 1; i < node->n; ++i)
- node->keys[i - 1] = node->keys[i];
- node->n--;
- }
- // Function to remove a key from the tree
- void remove(BTreeNode<T, ORDER>* node, T k) {
- int idx = 0;
- while (idx < node->n && node->keys[idx] < k)
- ++idx;
- if (idx < node->n && node->keys[idx] == k) {
- if (node->leaf)
- removeFromLeaf(node, idx);
- else
- removeFromNonLeaf(node, idx);
- } else {
- if (node->leaf) {
- cout << "The key " << k << " is not present in the tree\n";
- return;
- }
- bool flag = ((idx == node->n) ? true : false);
- if (node->children[idx]->n < ORDER / 2)
- fill(node, idx);
- if (flag && idx > node->n)
- remove(node->children[idx - 1], k);
- else
- remove(node->children[idx], k);
- }
- }
- public:
- BTree() { root = new BTreeNode<T, ORDER>(true); }
- // Function to insert a key in the tree
- void insert(T k) {
- if (root->n == ORDER - 1) {
- BTreeNode<T, ORDER>* s = new BTreeNode<T, ORDER>(false);
- s->children[0] = root;
- root = s;
- splitChild(s, 0);
- insertNonFull(s, k);
- } else
- insertNonFull(root, k);
- }
- // Function to traverse the tree
- void traverse() {
- if (root != nullptr)
- traverse(root);
- }
- // Function to search a key in the tree
- BTreeNode<T, ORDER>* search(T k) {
- return (root == nullptr) ? nullptr : search(root, k);
- }
- // Function to remove a key from the tree
- void remove(T k) {
- if (!root) {
- cout << "The tree is empty\n";
- return;
- }
- remove(root, k);
- if (root->n == 0) {
- BTreeNode<T, ORDER>* tmp = root;
- if (root->leaf)
- root = nullptr;
- else
- root = root->children[0];
- delete tmp;
- }
- }
- };
- int main() {
- BTree<int, 3> t;
- t.insert(10);
- t.insert(20);
- t.insert(5);
- t.insert(6);
- t.insert(12);
- t.insert(30);
- t.insert(7);
- t.insert(17);
- cout << "Traversal of the constructed tree is: ";
- t.traverse();
- cout << endl;
- int k = 6;
- (t.search(k) != nullptr) ? cout << k << " is found" << endl
- : cout << k << " is not found" << endl;
- k = 15;
- (t.search(k) != nullptr) ? cout << k << " is found" << endl
- : cout << k << " is not found" << endl;
- t.remove(6);
- cout << "Traversal of the tree after removing 6: ";
- t.traverse();
- cout << endl;
- t.remove(13);
- cout << "Traversal of the tree after removing 13: ";
- t.traverse();
- cout << endl;
- return 0;
- }
|