37 - Data Structure and Algorithms - B Trees
37 - Data Structure and Algorithms - B Trees
B Trees
They are general form of a Binary Search Tree as it holds more than one key
and two children.
Every node in a B tree, except root and leaf, can hold at least m/2
children
All the paths in a B tree must end at the same level, i.e. the leaf nodes
must be at the same level.
B trees are also widely used in disk access, minimizing the disk access time
since the height of a b tree is low.
Note − A disk access is the memory access to the computer disk where the
information is stored and disk access time is the time taken by the system to
access the disk memory.
The operations supported in B trees are Insertion, deletion and searching with
the time complexity of O(log n) for every operation.
Insertion
The insertion operation for a B Tree is done similar to the Binary Search Tree
but the elements are inserted into the same node until the maximum keys are
reached. The insertion is done using the following procedure −
Step 1 − Calculate the maximum $\mathrm{\left ( m-1 \right )}$ and minimum $\
mathrm{\left ( \left \lceil \frac{m}{2}\right \rceil-1 \right )}$ number of keys a
node can hold, where m is denoted by the order of the B Tree.
Step 2 − The data is inserted into the tree using the binary search insertion and
once the keys reach the maximum number, the node is split into half and the
median key becomes the internal node while the left and right keys become its
children.
Step 3 − All the leaf nodes must be on the same level.
The keys, 5, 3, 21, 9, 13 are all added into the node according to the binary
search property but if we add the key 22, it will violate the maximum key
property. Hence, the node is split in half, the median key is shifted to the
parent node and the insertion is then continued.
Another hiccup occurs during the insertion of 11, so the node is split and
median is shifted to the parent.
While inserting 16, even if the node is split in two parts, the parent node also
overflows as it reached the maximum keys. Hence, the parent node is split first
and the median key becomes the root. Then, the leaf node is split in half the
median of leaf node is shifted to its parent.
Example
int flag, i;
if (flag)
}
Deletion
Case 1 − If the key to be deleted is in a leaf node and the deletion does not
violate the minimum key property, just delete the node.
Case 2 − If the key to be deleted is in a leaf node but the deletion violates the
minimum key property, borrow a key from either its left sibling or right sibling.
In case if both siblings have exact minimum number of keys, merge the node
in either of them.
// Deletion operation
if (leaf)
deletion_at_leaf(index);
else
deletion_at_nonleaf(index);
} else {
if (leaf) {
cout << "key " << key << " does not exist in the tree\n";
return;
if (C[index]->n < t)
fill(index);
C[index - 1]->deletion(key);
else
C[index]->deletion(key);
return;
}
keys[i - 1] = keys[i];
n--;
return;
if (C[index]->n >= t) {
keys[index] = pred;
C[index]->deletion(pred);
C[index + 1]->deletion(successor);
} else {
merge(index);
C[index]->deletion(key);
return;
C++ Implementation
#include<iostream>
int *d;
BTree **child_ptr;
bool l;
int n;
int i;
np = new BTree;
np->l = true;
np->n = 0;
np->child_ptr[i] = NULL;
return np;
cout<<endl;
int i;
if (p->l == false) {
traverse(p->child_ptr[i]);
}
if (p->l == false) {
traverse(p->child_ptr[i]);
cout<<endl;
int i, j, t;
if (p[i] >p[j]) {
t = p[i];
p[i] = p[j];
p[j] = t;
}
}
int j, mid;
np3->l = true;
if (i == -1) {
x->d[2] = 0;
x->n--;
np1 = init();
np1->l= false;
x->l= true;
np3->d[j - 3] = x->d[j];
np3->child_ptr[j - 3] = x->child_ptr[j];
np3->n++;
x->d[j] = 0;
x->n--;
x->child_ptr[j] = NULL;
np1->d[0] = mid;
np1->child_ptr[np1->n] = x;
np1->child_ptr[np1->n + 1] = np3;
np1->n++;
r = np1;
} else {
y = x->child_ptr[i];
mid = y->d[2];
y->d[2] = 0;
y->n--;
np3->d[j - 3] = y->d[j];
np3->n++;
y->d[j] = 0;
y->n--;
x->child_ptr[i + 1] = y;
x->child_ptr[i + 1] = np3;
return mid;
void insert(int a) {
int i, t;
x = r;
if (x == NULL) {
r = init();
x = r;
} else {
t = split_child(x, -1);
x = r;
for (i = 0; i < (x->n); i++) {
i++;
break;
break;
} else {
continue;
x = x->child_ptr[i];
} else {
i++;
break;
break;
} else {
continue;
if ((x->child_ptr[i])->n == 6) {
t = split_child(x, i);
x->d[x->n] = t;
x->n++;
continue;
} else {
x = x->child_ptr[i];
x->d[x->n] = a;
sort(x->d, x->n);
x->n++;
}
int main() {
int i, n, t;
insert(10);
insert(20);
insert(30);
insert(40);
insert(50);
cout<<"B tree:\n";
traverse(r);
Output
B tree:
10 20 30 40 50