×

Insertion in B+ Tree

We will learn how to insert a node in the B+ tree and what are the different properties we are going to follow.

Except for the root node, every node should have a maximum of Children at least ceil(M/2) children.

The root node must contain at least two children and at least one search key.

Steps for insertion at root node:

  1. Every element must be inserted in the leaf node.
  2. If an overflow situation occurs in the leaf nodes, we must follow the following steps to overcome the overflow.
    • Partition the leaf into two different nodes along with the other nodes.
    • The starting node contains the ceiling value of (m-1)/2.
    • The next node contains the remaining nodes from the above nodes.
    • Insert the element in the left base node in the Right-biased tree.

Code for the insertion at B+ Tree

// C++ program for implementing B+ Tree
#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 insert internal(int,
Node*,
Node*);
Node* findParent(Node*, Node*);
public:
BPTree();
void search(int);
void insert(int);
void display(Node*);
Node* getRoot();
};
// Constructor of Node
Node::Node()
{
key = new int[MAX];
ptr = new Node*[MAX + 1];
}
// Initialise the BPTree Node
BPTree::BPTree()
{
root = NULL;
}
// Function to find any element
// in B+ Tree
void BPTree::search(int x)
{
// If the tree is empty
if (root == NULL) {
cout << "Tree is empty\n";
}
// Traverse to find the value
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 reaches the end of the
// cursor node
if (i == cursor->size - 1) {
cursor = cursor->ptr[i + 1];
break;
}
}
}
for (int i = 0;
i < cursor->size; i++) {
// If found then return
if (cursor->key[i] == x) {
cout << "Found\n";
return;
}
}
// Else element is not present
cout << "Not found\n";
}
}
// Function to implement the Insert
void BPTree::insert(int x)
{
if (root == NULL) {
root = new Node;
root->key[0] = x;
root->IS_LEAF = true;
root->size = 1;
}
// Traverse the B+ Tree
else {
Node* cursor = root;
Node* parent;
while (cursor->IS_LEAF
== false) {
parent = cursor;
for (int i = 0;
i < cursor->size;
i++) {
// If found the position
// where we have to insert
// node
if (x < cursor->key[i]) {
cursor
= cursor->ptr[i];
break;
}
// If reaches the end
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 {
// Create a newLeaf node
Node* newLeaf = new Node;
int virtualNode[MAX + 1];
// node created
for (int i = 0; i < MAX; i++) {
virtualNode[i]
= cursor->key[i];
}
int i = 0, j;
// Traverse to find where the new
while (x > virtualNode[i]
&& i < MAX) {
i++;
}
// Update the current virtual
// Node to its previous
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;
// Update the current virtual
// Node's key to its previous
for (i = 0;
i < cursor->size; i++) {
cursor->key[i]
= virtualNode[i];
}
// Update the newLeaf key to
// virtual Node
for (i = 0, j = cursor->size;
i < newLeaf->size;
i++, j++) {
newLeaf->key[i]
= virtualNode[j];
}
// If the cursor is the root node
if (cursor == root) {
Node* newRoot = new Node;
// Update the rest field of
// B+ Tree 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 {
// Recursive Call for
// insert in internal
insertInternal(newLeaf->key[0],
parent,
newLeaf);
}
}
}
}
// Function to implement the Insert
// Internal Operation in B+ Tree
void BPTree::insertInternal(int x,
Node* cursor,
Node* child)
{
// If we don’t have overflow
if (cursor->size < MAX) {
int i = 0;
// Traverse the child node
// for current cursor node
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;
// Traverse to find where the new
while (x > virtualKey[i]
&& i < MAX) {
i++;
}
// Traverse the virtual node
// and update the current key
// to its previous node key
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;
// Insert a new node as an
// internal node
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 the cursor is the root node
if (cursor == root) {
// Create a new root node
Node* newRoot = new Node;
// Update key value
newRoot->key[0]
= cursor->key[cursor->size];
// Update the rest field of
// B+ Tree Node
newRoot->ptr[0] = cursor;
newRoot->ptr[1] = newInternal;
newRoot->IS_LEAF = false;
newRoot->size = 1;
root = newRoot;
}
else {
// Recursive Call to insert
// the data
insertInternal(cursor->key[cursor->size],
findParent(root,
cursor),
newInternal);
}
}
}
// Function to find the parent node
Node* BPTree::findParent(Node* cursor,
Node* child)
{
Node* parent;
// If the cursor reaches the end of the Tree
if (cursor->IS_LEAF
|| (cursor->ptr[0])->IS_LEAF) {
return NULL;
}
// Traverse the current node with
// all its child
for (int i = 0;
i < cursor->size + 1; i++) {
// Update the parent for the
// child Node
if (cursor->ptr[i] == child) {
parent = cursor;
return parent;
}
// Else recursively traverse to
// find child node
else {
parent
= findParent(cursor->ptr[i],
child);
// If a parent is found, then
// return that parent node
if (parent != NULL)
return parent;
}
}
// Return parent node
return parent;
}
// Function to get the root Node
Node* BPTree::getRoot()
{
return root;
}
// Driver Code
int main()
{
BPTree node;
// Create B+ Tree
node.insert(20);
node.insert(109);
node.insert(76);
node.insert(82);
node.insert(55);
// Function Call to search node
// with value 76
node.search(76);
return 0;
}

Related Topics

What are the types of Trees in Data Structure

Data structures Data management is called database management. This allows the computer to sort or organize the data for efficient retrieval. A data model is a system used to store, manage,...

6 minutes read.

Delete N nodes after M nodes of a linked list

Delete N nodes after M nodes of a linked list In this problem, we have given a linked list and two integers M and N. We need to traverse the linked...

3 minutes read.

Given a Binary Tree Print the Shortest Path

Implementation // Writing a program in C++ to find the shortest between the nodes i and j.  #include <bits/stdc++.h> using namespace std; // the given function will print the path between nodes i and...

7 minutes read.

Applications of Different Linked Lists in Data Structure

What is a Linked list? A linked list is a data structure that consists of a sequence of elements, where each containing a reference or ("link") to the next element in...

5 minutes read.

Segregate Even and Odd nodes in a Linked List

Segregate even and odd nodes in a Linked List In this problem, we have given a linked list with integer numbers. We need to modify the given linked list in such...

4 minutes read.

Horizontal and Vertical Scaling

Being a software engineer, you would have designed a website or application and deployed it on any server. Imagine that the developed application starts getting popular, and many users engage...

6 minutes read.

Breadth First Search

Breadth First Search Breadth first search is a graph traversing algorithm. In this, we start traversing from the source node or any selected node and traverse the graph layer by layer....

6 minutes read.

Tree in Data Structure

Tree A tree is a non-linear data structure by which hierarchical data is displayed. As we know that there are many trees in the forest, similarly the data structure also contains...

3 minutes read.

Queue operations in Data Structure

Queue - Queue is a linear data structure or first in first out data structure means the first element added in the queue will be removed first and the last...

7 minutes read.

Applications of trees in data structures

Data structures Storage used to organize and store data is known as the data structure. It is a method of managing computerized data to translate or retrieve it more efficiently. A...

7 minutes read.

Deletion Operation of the binary search tree in C++ language

A typical binary search tree implements some order to carry out the arrangements. As the name suggests, each parent node should have at most two children. The main rule in...

4 minutes read.

Bottom view of the binary tree

The bottom of the binary tree is generally defined as the number of nods present in the bottom-most part of the tree. In this article, we will see the implementation...

3 minutes read.

Stack vs Queue: Data Structure

 Difference Between Stack and Queue What is Stack? The LIFO principle applies on insertion and deletion operations of the stack which means last inserted element to the stack will remove first....

3 minutes read.

Polish Notation in Data Structures

Arithmetic Expression: An arithmetic expression is defined as several operands or data items combined using several operators. For example; a+b*(c-d) is an expression. Operands: Operands represent the data in an expression...

2 minutes read.

Left View of Binary Tree

Implementation // creating a C++ program to print the Left view of the binary tree. #include <bits/stdc++.h> using namespace std; struct Nod { int record; struct Nod *Lft, *Rt; }; // creating a utility function that will eventually help...

4 minutes read.

Advantages and Disadvantages of Linked List

Advantages of Linked List The linked list is a dynamic data structure.You can also decrease and increase the linked list at run-time. That is, you can allocate and deallocate memory at...

3 minutes read.

Queue Data Structure

Queue in DS: The queue is a non-primitive and linear data structure. It works on the principle of FIFO (First In First Out). That is, the element that is added...

4 minutes read.

Primitive Data Structure in C

The data structure is a logical or mathematical model for organizing and structuring the main memory or elements. We can classify the data structures in two ways one is primitive, and...

10 minutes read.

Top view of binary tree

We know that a binary tree is a kind of tree that helps us organize our tree and that it is a kind of non-linear info structure that at least...

4 minutes read.

Operations on 1D-Arrays

One Dimensional Array Operations Basic Methods The fundamental operations enabled by an array are listed below. Traverse prints each element of the array one by one.Insert a new element at the specified index.Delete...

8 minutes read.