×

Operations of B Tree in C++ Language

B tree tends to be a self-aligning and balancing tree that helps us organise our data and document safely. We know that every data or information in the B tree gets stored in the main memory. It is a fact that when the amount of data to be considered is pretty huge. The data is not stored in the computer's main memory; instead, the task is achieved via reading the data and bringing it out to the destination in the form of blocks. The disk access time is minimal when we compare it to many other non-linear data structures.

Several operations are used in the B tree to help us perform functions to manage our data. Some of them are searching, insertion, deletion, and several others. The searching operation is mainly used to search a given element when required, on the contrary, the deletion operation is often used when we need to delete a specific part from the tree, and the insertion element is necessary when we want to insert or push a new element into the B tree.

We will see some examples of these operations in detail.

Example1)

#include <iostream>
using namespace std;


class N {
  int *kys;
  int r;
  Nod **C;
  int g;
  bool leaf;


   public:
  Nod(int _r, bool _leaf);


  void insertNonFull(int m);
  void splitChild(int i, Nod *y);
  void traverse();


  friend class B_Tree;
};


class B_Tree {
  Nod *root;
  int r;


   public:
  B_Tree(int _r) {
    root = NILL;
    r = _r;
  }


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


  void insert(int m);
};


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


  kys = new int[2 * t - 1];
  C = new Nod *[2 * t];


  n = 0;
}


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


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


// Insert the Nod
void B_Tree::insert(int m) {
  if (root == NILL) {
    root = new Nod(t, true);
    root->kys[0] = k;
    root->n = 1;
  } else {
    if (root->n == 2 * r - 1) {
      Nod *s = new Nod(r, false);


      s->P[0] = root;


      s->splitChild(0, root);


      int i = 0;
      if (s->kys[0] < m)
        i++;
      s->P[i]->insertNonFull(m);


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


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


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


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


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


      if (kys[i + 1] < m)
        i++;
    }
    C[i + 1]->insertNonFull(m);
  }
}


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


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


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


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


  P[i + 1] = z;


  for (int j = g - 1; j >= i; j--)
    kys[j + 1] = kys[j];


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


int main() {
  B_Tree 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();
}

Output:

OPERATIONS OF B TREE IN C++ LANGUAGE

Deletion

// Deleting a key from a B-tree

#include <iostream>
using namespace std;


class B_TreeNod {
  int *kys;
  int r;
  B_TreeNod **C;
  int g;
  bool leaf;


   public:
  B_TreeNod(int _t, bool _leaf);


  void traverse();


  int findKey(int m);
  void insertNonFull(int m);
  void splitChild(int i, B_TreeNod *y);
  void deletion(int m);
  void eliminateFromLeaf(int IX);
  void eliminateFromNonLeaf(int IX);
  int get_Predd(int IX);
  int get_Succ(int IX);
  void fill(int IX);
  void borrowFromPast(int IX);
  void borrowFromComing(int IX);
  void merge(int IX);
  friend class B_Tree;
};


class B_Tree {
  B_TreeNod *root;
  int r;


   public:
  B_Tree(int _t) {
    root = NILL;
    r = _r;
  }


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


  void insertion(int m);


  void deletion(int m);
};


// B tree Nod
B_TreeNod::B_TreeNod(int r1, bool leaf1) {
  r = r1;
  leaf = leaf1;


  kys = new int[2 * r - 1];
  P = new B_TreeNod *[2 * r];


  g = 0;
}


// Find the key
int B_TreeNod::findKey(int m) {
  int IX = 0;
  while (IX < g && kys[IX] < m)
    ++IX;
  return IX;
}


// Deletion operation
void B_TreeNod::deletion(int m) {
  int IX = findKey(m);


  if (IX < g && kys[IX] == m) {
    if (leaf)
      removeFromLeaf(IX);
    else
      removeFromNonLeaf(IX);
  } else {
    if (leaf) {
      cout << "The key " << m << " is does not exist in the tree”<<endl;
      return;
    }


    bool flag = ((IX == g) ? true : false);


    if (P[IX]->g < r)
      fill(IX);


    if (flag && IX > n)
      P[IX - 1]->deletion(m);
    else
      P[IX]->deletion(m);
  }
  return;
}


// Remove from the leaf
void B_TreeNod::removeFromLeaf(int IX) {
  for (int i = IX + 1; i < n; ++i)
    kys[i - 1] = kys[i];


  n--;


  return;
}


// Delete from non-leaf 
void B_TreeNod::EliminateFromNonLeaf(int IX) {
  int m = kys[ix];


  if (P[ix]->g >= t) {
    int pred = get_Predd(ix);
    kys[IX] = pred;
    P[IX]->deletion(pred);
  }


  else if (P[IX + 1]->n >= t) {
    int succ = get_Succ(IX);
    kys[IX] = succ;
    C[IX + 1]->deletion(succ);
  }


  else {
    merge(IX);
    C[IX]->deletion(k);
  }
  return;
}


int B_TreeNod::get_Predd(int IX) {
  B_TreeNod *cur = C[IX];
  while (!cur->leaf)
    cur = cur->C[cur->n];


  return cur->kys[cur->n - 1];
}


int B_TreeNod::get_Succ(int IX) {
  B_TreeNod *cur = C[IX + 1];
  while (!cur->leaf)
    cur = cur->C[0];


  return cur->kys[0];
}


void B_TreeNod::fill(int IX) {
  if (IX != 0 && C[IX - 1]->n >= t)
    borrowFromPast(IX);


  else if (IX != n && P[ix + 1]->g >= t)
    borrowFromComing(ix);


  else {
    if (IX != g)
      merge(IX);
    else
      merge(IX - 1);
  }
  return;
}


// Borrow from previous
void B_TreeNod::borrowFromPast(int IX) {
  B_TreeNod *child = C[IX];
  B_TreeNod *sibb = P[ix - 1];


  for (int i = child->g - 1; i >= 0; --i)
    child->Kys[i + 1] = child->kys[i];


  if (!child->leaf) {
    for (int i = child->g; i >= 0; --i)
      child->P[i + 1] = child->C[i];
  }


  child->kys[0] = kys[ix - 1];


  if (!child->leaf)
    child->P[0] = sibb->P[sibb->g];


  kys[IX - 1] = sibling->kys[sibling->n - 1];


  child->n += 1;
  sibling->n -= 1;


  return;
}


// Borrow from the next
void B_TreeNod::borrowFromComing(int IX) {
  B_TreeNod *child = C[IX];
  B_TreeNod *sibling = C[IX + 1];


  child->kys[(child->n)] = kys[IX];


  if (!(child->leaf))
    child->C[(child->n) + 1] = sibling->C[0];


  kys[IX] = sibling->kys[0];


  for (int i = 1; i < sibb->g; ++i)
    sibb->kys[i - 1] = sibling->kys[i];


  if (!sibling->leaf) {
    for (int i = 1; i <= sibb->g; ++i)
      sibling->C[i - 1] = sibb->P[i];
  }


  child->n += 1;
  sibling->n -= 1;


  return;
}


// Merge
void B_TreeNod::merge(int IX) {
  B_TreeNod *child = C[IX];
  B_TreeNod *sibling = C[IX + 1];


  child->kys[t - 1] = kys[IX];


  for (int i = 0; i < sibling->n; ++i)
    child->kys[i + t] = sibling->kys[i];


  if (!child->leaf) {
    for (int i = 0; i <= sibling->n; ++i)
      child->C[i + t] = sibling->C[i];
  }


  for (int i = IX + 1; i < n; ++i)
    kys[i - 1] = kys[i];


  for (int i = IX + 2; i <= n; ++i)
    C[i - 1] = C[i];


  child->n += sibling->n + 1;
  n--;


  delete (sibling);
  return;
}


// Insertion operation
void B_Tree::insertion(int m) {
  if (root == NILL) {
    root = new B_TreeNod(t, true);
    root->kys[0] = k;
    root->n = 1;
  } else {
    if (root->n == 2 * t - 1) {
      B_TreeNod *s = new B_TreeNod(t, false);


      s->C[0] = root;


      s->splitChild(0, root);


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


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


// Insertion non full
void B_TreeNod::insertNonFull(int m) {
  int i = n - 1;


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


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


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


      if (kys[i + 1] < m)
        i++;
    }
    P[i + 1]->insertNonFull(m);
  }
}


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


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


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


  y->g = t - 1;


  for (int j = g; j >= i + 1; j--)
    P[j + 1] = P[j];


  P[i + 1] = z;


  for (int j = g - 1; j >= i; j--)
    kys[j + 1] = kys[j];


  kys[i] = y->kys[t - 1];


  n = n + 1;
}


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


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


// Delete Operation
void B_Tree::deletion(int m) {
  if (!root) {
    cout << "The tree is empty\n";
    return;
  }


  root->deletion(k);


  if (root->n == 0) {
    B_TreeNod *tmp = root;
    if (root->leaf)
      root = NILL;
    else
      root = root->C[0];


    delete tmp;
  }
  return;
}


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


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


  t.deletion(20);


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

Output:

OPERATIONS OF B TREE IN C++ LANGUAGE

Searching

#include <iostream>
using namespace std;


class TreeNod {
  int *kys;
  int r;
  TreeNod **C;
  int g;
  bool leaf;


   public:
  TreeNod(int remp, bool bool_leaf);


  void insertNonFull(int m);
  void splitChild(int i, TreeNod *y);
  void traverse();


  TreeNod *search(int m);


  friend class B_Tree;
};


class B_Tree {
  TreeNod *root;
  int r;


   public:
  B_Tree(int remp) {
    root = NILL;
    t = temp;
  }


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


  TreeNod *search(int m) {
    return (root == NILL) ? NILL : root->search(k);
  }


  void insert(int m);
};


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


  kys = new int[2 * t - 1];
  C = new TreeNod *[2 * t];


  n = 0;
}


void TreeNod::traverse() {
  int i;
  for (i = 0; i < n; i++) {
    if (leaf == false)
      C[i]->traverse();
    cout << " " << kys[i];
  }


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


TreeNod *TreeNod::search(int m) {
  int i = 0;
  while (i < n && k > kys[i])
    i++;


  if (kys[i] == k)
    return this;


  if (leaf == true)
    return NILL;


  return C[i]->search(k);
}


void B_Tree::insert(int m) {
  if (root == NILL) {
    root = new TreeNod(t, true);
    root->kys[0] = k;
    root->n = 1;
  } else {
    if (root->n == 2 * t - 1) {
      TreeNod *s = new TreeNod(t, false);


      s->C[0] = root;


      s->splitChild(0, root);


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


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


void TreeNod::insertNonFull(int m) {
  int i = n - 1;


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


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


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


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


void TreeNod::splitChild(int i, TreeNod *y) {
  TreeNod *z = new TreeNod(y->t, y->leaf);
  z->n = t - 1;


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


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


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


  P[i + 1] = z;


  for (int j = g - 1; j >= i; j--)
    kys[j + 1] = kys[j];


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


int main() {
  B_Tree 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();


  int m = 10;
  (t.search(k) != NILL) ? cout << endl
                 << k << " is found"
              : cout << endl
                 << k << " is not Found";


  k = 2;
  (t.search(k) != NILL) ? cout << endl
                 << k << " is found"
              : cout << endl
                 << k << " is not Found\n";
}

Output:

OPERATIONS OF B TREE IN C++ LANGUAGE

Related Topics

Vertical Order Traversal of Binary Tree

Implementation #include <iostream> #include <vector> #include <map> using namespace std; // representing the primary model of a binary tree node. struct _nod { int ky; _nod *Lft, *Rt; }; // establishing a new function representing the new binary tree node. struct _nod*...

5 minutes read.

Threaded Binary Tree

The linked form of binary trees wastes storage capacity because more than half of the connection variables have a Missing value. A binary tree has several nodes. Hence n+1 link fields...

8 minutes read.

Post-order traversal in a binary tree

We all know that postorder is a form of tree traversal to visit the tree's nodes, and it helps us reach out to the tree's nodes. Postorder means visiting the...

4 minutes read.

Binary Search Tree

Binary Search Tree: A binary search tree is a type of tree in which every node is organized in the sorted order. It is also called an ordered binary tree. Properties...

4 minutes read.

Deletion in Binary Search Tree

Implementation #include <iostream> using namespace std; struct _nod {   int ky;   struct _nod *Lft, *Rt; }; // Creating a node in the binary tree. struct _nod *nw_nod(int Itm) {   struct _nod *temp = (struct _nod *)malloc(sizeof(struct...

4 minutes read.

Number of visible boxes putting one inside another

You have given one array, which consists of values which represent the sizes of different boxes. We can put one box inside another if the size of the outside box...

3 minutes read.

Convert Binary Tree into a Threaded Binary Tree

Implementation /*Writing a C++ program that will help us change the binary tree into a threaded binary tree and help us transform. */ #include <bits/stdc++.h> using namespace std; /*Creating the structure of a node...

11 minutes read.

Detect Loop in Linked List: Data Structure

Detect the Loop in Linked List: In this problem, we will be seeing some technique through which we can detect the loop in linked list. We will discuss each technique...

3 minutes read.

Linked List Representation of Binary Tree

As we all know, a binary tree has a maximum of two children and helps us manage the info correctly. The word binary itself represents its meaning; we know that...

4 minutes read.

Given a Binary Tree, find its Minimum Depth

Implementation // Creating a C++ program or implementation to search and explore the minimum depth of a given binary tree.  #include<bits/stdc++.h> using namespace std; // Creating a new binary tree node struct __nod { int record; struct __nod*...

5 minutes read.

Print kth least significant bit number

You have given a number and you have to find out the kth least significant bit of this number. K will be given to you.  The bit will be from...

3 minutes read.

Application of Stack in Data Structures

In this article, we will discuss all the different applications of stack. What is meant by stack? The stack is a non-primitive linear data structure in which the insertion of the new...

11 minutes read.

What is a full Binary Tree?

A full binary tree is considered to be a special kind of binary tree in which every single node or leaf node present either contains two children or no children...

4 minutes read.

Blowfish algorithm

The Blowfish algorithm is the very first encryption algorithm which is symmetric. It was firstly used as an alternate algorithm for the DES algorithm. It was designed by Bruce Steiner...

3 minutes read.

Reverse a Linked List in groups of given size

Reverse a Linked List in groups of given size This article will explain how to reverse a linked list in groups of given size. Here we have given a linked list...

2 minutes read.

Application of 2D array - Sparse Matrix

2D Arrays Application - Sparse Matrix A matrix is a two-dimensional data item consisting of m rows and n columns, with a total of m x n values. A sparse matrix...

7 minutes read.

AVL Tree

AVL Tree AVL Tree is referred to as self-balanced or height-balanced binary search tree where the difference between heights of its left subtree and right subtree (Balance Factor) can't more than...

25 minutes read.

Stack Using Linked List

In the linked list implementation of the stack, we use a linked list as the primitive data structure to create the stack. It is called the dynamic implementation of the...

6 minutes read.

Linked List Data Structure

Linked list in DS: The linked list is a non-primitive and linear data structure. It is a list of a particular type of data element that is connected to each...

3 minutes read.

What is a Tree in Terms of a Graph?

To know the explanation of trees in terms of graphs, we need first to know what trees and graphs are. So let us first learn about trees and graphs. Trees and...

6 minutes read.