B-Tree Insert and In-Order Traversal in Python

Simulates a B-tree (order 2) with insert and split logic, then prints keys in sorted order via in-order traversal.

Hard Python 3.9+ Aug 9, 2026 Database scaling & optimization 13 views 0 copies

Python code

72 lines
Python 3.9+
class BTreeNode:
    def __init__(self, leaf=False):
        self.leaf = leaf
        self.keys = []
        self.children = []

    def is_full(self, t):
        return len(self.keys) == 2 * t - 1


class BTree:
    def __init__(self, t=2):
        self.t = t
        self.root = BTreeNode(leaf=True)

    def insert(self, key):
        if self.root.is_full(self.t):
            new_root = BTreeNode(leaf=False)
            new_root.children.append(self.root)
            self._split_child(new_root, 0)
            self.root = new_root
        self._insert_non_full(self.root, key)

    def _split_child(self, parent, i):
        t = self.t
        child = parent.children[i]
        new_child = BTreeNode(leaf=child.leaf)
        parent.keys.insert(i, child.keys[t - 1])
        parent.children.insert(i + 1, new_child)
        new_child.keys = child.keys[t:]
        child.keys = child.keys[:t - 1]
        if not child.leaf:
            new_child.children = child.children[t:]
            child.children = child.children[:t]

    def _insert_non_full(self, node, key):
        if node.leaf:
            i = 0
            while i < len(node.keys) and key > node.keys[i]:
                i += 1
            node.keys.insert(i, key)
        else:
            i = 0
            while i < len(node.keys) and key > node.keys[i]:
                i += 1
            if node.children[i].is_full(self.t):
                self._split_child(node, i)
                if key > node.keys[i]:
                    i += 1
            self._insert_non_full(node.children[i], key)

    def to_list(self):
        result = []

        def traverse(node):
            if node.leaf:
                result.extend(node.keys)
            else:
                for i in range(len(node.keys)):
                    traverse(node.children[i])
                    result.append(node.keys[i])
                traverse(node.children[-1])

        traverse(self.root)
        return result


if __name__ == "__main__":
    tree = BTree(t=2)
    for value in [10, 20, 5, 6, 12, 30, 7, 17]:
        tree.insert(value)
    print(tree.to_list())

Output

stdout
[5, 6, 7, 10, 12, 17, 20, 30]

How it works

A B-tree keeps keys sorted in each node and splits full nodes when they reach 2t-1 keys. The _split_child method promotes the middle key to the parent and divides the child into two nodes. _insert_non_full descends recursively to a leaf, inserting in order or splitting along the way. The to_list method performs an in-order traversal, visiting children before and after each key, which yields sorted output. With t=2, the tree is a 2-3-4 tree.

Common mistakes

  • Forgetting to split the root when it becomes full, losing the tree height increase
  • Not handling the case where the key is greater than the promoted key after a split in insert
  • Assuming leaf nodes have children or vice versa in traversal

Variations

  1. Use `sorted(tree.to_list())` to get the same result without relying on in-order logic

Real-world use cases

  • Simulating database index behavior before implementing with real storage engines.
  • Teaching or explaining B-tree insertion and node splitting algorithms in coursework.
  • Prototyping balanced search structures that minimize disk I/O for large datasets.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Database scaling & optimization

Related tutorials and quizzes for this topic.