codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Tutorials
🧮

Data Structures & Algorithms

17 / 65 topics
13Binary Search Trees (BSTs)14Balanced Binary Search Trees15AVL Trees16Red-Black Trees17B-Trees18Graphs Basics19Graph Representations (Adjacency List, Matrix)64AVL Trees Advantages and Disadvantages65Red-Black Trees Advantages and Disadvantages
Tutorials/Data Structures & Algorithms/B-Trees
🧮Data Structures & Algorithms

B-Trees

Updated 2026-04-20
2 min read

Introduction

B-Trees are a type of self-balancing tree data structure that maintains sorted data and allows searches, sequential access, insertions, and deletions in logarithmic time. They are particularly useful for storage systems like databases and file systems because they can efficiently handle large amounts of data stored on disk.

Key Characteristics of B-Trees

  1. Balanced Tree: All leaf nodes are at the same depth.
  2. Multiple Children: Each node can have multiple children, typically between t and 2t-1.
  3. Sorted Keys: Keys within a node are sorted, and each key separates the sub-trees for which keys fall below or above it.
  4. Leaf Nodes: All leaf nodes are at the same level and contain no data.

Structure of a B-Tree Node

A B-tree node consists of:

  • Keys: An array of t-1 to 2t-2 keys.
  • Children Pointers: An array of t to 2t child pointers.
  • Leaf Flag: A boolean flag indicating whether the node is a leaf.

Operations on B-Trees

1. Search Operation

The search operation in a B-tree is similar to binary search in a binary tree but adapted for multiple keys per node.

function search(node, key) {
    let i = 0;
    while (i < node.keys.length && key > node.keys[i]) {
        i++;
    }
    if (node.leaf) {
        return i < node.keys.length && node.keys[i] === key ? node : null;
    } else {
        return search(node.children[i], key);
    }
}

2. Insert Operation

Insertion in a B-tree involves finding the correct position for the new key and inserting it. If a node overflows (more than 2t-1 keys), it is split into two nodes.

function insertNonFull(node, key) {
    let i = node.keys.length - 1;
    if (node.leaf) {
        while (i >= 0 && key < node.keys[i]) {
            node.keys[i + 1] = node.keys[i];
            i--;
        }
        node.keys[i + 1] = key;
    } else {
        while (i >= 0 && key < node.keys[i]) {
            i++;
        }
        if (node.children[i].keys.length === 2 * t - 1) {
            splitChild(node, i);
            if (key > node.keys[i]) {
                i++;
            }
        }
        insertNonFull(node.children[i], key);
    }
}

function splitChild(parent, index) {
    const child = parent.children[index];
    const newChild = new BTreeNode(t, true);

    for (let j = 0; j < t - 1; j++) {
        newChild.keys[j] = child.keys[j + t];
    }

    if (!child.leaf) {
        for (let j = 0; j < t; j++) {
            newChild.children[j] = child.children[j + t];
        }
    }

    child.keys.length = t - 1;
    parent.children.splice(index + 1, 0, newChild);
    for (let j = parent.keys.length - 1; j >= index; j--) {
        parent.keys[j + 1] = parent.keys[j];
    }
    parent.keys[index] = child.keys[t - 1];
}

3. Delete Operation

Deletion in a B-tree is more complex due to the need to maintain the minimum degree t. If a node underflows (fewer than t-1 keys), it may be merged with a sibling or borrow a key from one.

function deleteKey(node, key) {
    let index = 0;
    while (index < node.keys.length && key > node.keys[index]) {
        index++;
    }

    if (node.leaf) {
        if (index < node.keys.length && node.keys[index] === key) {
            node.keys.splice(index, 1);
        }
    } else {
        if (index < node.keys.length && node.keys[index] === key) {
            if (node.children[index].keys.length >= t) {
                let pred = getPred(node, index);
                node.keys[index] = pred;
                deleteKey(node.children[index], pred);
            } else if (node.children[index + 1].keys.length >= t) {
                let succ = getSucc(node, index);
                node.keys[index] = succ;
                deleteKey(node.children[index + 1], succ);
            } else {
                merge(node, index);
                deleteKey(node.children[index], key);
            }
        } else {
            if (node.children[index].keys.length < t) {
                fill(index);
            }
            if (index > node.keys.length && node.children[index - 1]) {
                deleteKey(node.children[index - 1], key);
            } else {
                deleteKey(node.children[index], key);
            }
        }
    }
}

Best Practices

  • Choose an Appropriate t: The value of t affects the height and width of the tree. A larger t results in fewer levels but more keys per node, which can be beneficial for disk-based storage.
  • Disk-Based Storage: B-trees are optimized for disk access because they minimize the number of disk reads by keeping nodes large enough to contain many keys.
  • Balancing: Regularly rebalance the tree if operations skew the distribution of keys.

Conclusion

B-trees are a powerful data structure for managing large datasets efficiently. Their ability to maintain balance and handle multiple keys per node makes them ideal for applications requiring fast access, insertion, and deletion operations on disk-based storage systems. Understanding B-trees is crucial for developers working with databases and file systems.


PreviousRed-Black TreesNext Graphs Basics

Recommended Gear

Red-Black TreesGraphs Basics