B-tree Implementation in Python


B-tree Implementation in Python

A B-tree is a self-balancing tree data structure that maintains sorted data and allows for efficient insertion, deletion, and search operations. It is commonly used in database indexing due to its ability to maintain balance with a large number of keys and its efficiency in disk-based systems.

Program Structure

The B-tree implementation in Python consists of the following key components:

1. BTreeNode Class

This class represents a node in the B-tree. It includes the following properties:

  • keys: A list of keys stored in the node.
  • children: A list of child nodes. This list is empty for leaf nodes.
  • leaf: A boolean indicating whether the node is a leaf node.

2. BTree Class

This class encapsulates the functionality of the B-tree and includes the following methods:

  • __init__(self, t): Initializes the B-tree with a given minimum degree t.
  • search(self, k, x=None): Searches for a key k in the B-tree, starting from node x (defaults to the root).
  • insert(self, k): Inserts a new key k into the B-tree.
  • split_child(self, x, i): Splits the child node at index i of node x when it is full.
  • insert_non_full(self, x, k): Inserts a key k into a node x that is not full.

Python Code Implementation


class BTreeNode:
def __init__(self, t, leaf=False):
"""
Initialize a B-tree node.
:param t: Minimum degree (defines the range for number of keys).
:param leaf: Boolean flag indicating if the node is a leaf.
"""
self.t = t # Minimum degree
self.leaf = leaf # True if leaf node
self.keys = [] # List of keys in the node
self.children = [] # List of child pointers

def __str__(self):
return f"Keys: {self.keys}, Leaf: {self.leaf}"

class BTree:
def __init__(self, t):
"""
Initialize the B-tree.
:param t: Minimum degree (defines the range for number of keys).
"""
self.root = BTreeNode(t, True)
self.t = t # Minimum degree

def search(self, k, x=None):
"""
Search for a key in the B-tree.
:param k: The key to search for.
:param x: The node to start the search from (defaults to root).
:return: Tuple of (node, index) if key is found, otherwise None.
"""
if x is None:
x = self.root
i = 0
while i < len(x.keys) and k > x.keys[i]:
i += 1
if i < len(x.keys) and k == x.keys[i]:
return x, i
elif x.leaf:
return None
else:
return self.search(k, x.children[i])

def insert(self, k):
"""
Insert a key into the B-tree.
:param k: The key to insert.
"""
root = self.root
if len(root.keys) == (2 * self.t) - 1:
s = BTreeNode(self.t)
self.root = s
s.children.append(root)
self.split_child(s, 0)
self.insert_non_full(s, k)
else:
self.insert_non_full(root, k)

def split_child(self, x, i):
"""
Split the child of a node.
:param x: The node whose child is to be split.
:param i: The index of the child in the children list.
"""
t = self.t
y = x.children[i]
z = BTreeNode(t, y.leaf)
x.children.insert(i + 1, z)
x.keys.insert(i, y.keys[t - 1])
z.keys = y.keys[t: (2 * t) - 1]
y.keys = y.keys[0: t - 1]
if not y.leaf:
z.children = y.children[t: 2 * t]
y.children = y.children[0: t]

def insert_non_full(self, x, k):
"""
Insert a key into a node that is not full.
:param x: The node to insert the key into.
:param k: The key to insert.
"""
i = len(x.keys) - 1
if x.leaf:
x.keys.append(None)
while i >= 0 and k < x.keys[i]:
x.keys[i + 1] = x.keys[i]
i -= 1
x.keys[i + 1] = k
else:
while i >= 0 and k < x.keys[i]:
i -= 1
i += 1
if len(x.children[i].keys) == (2 * self.t) - 1:
self.split_child(x, i)
if k > x.keys[i]:
i += 1
self.insert_non_full(x.children[i], k)

Explanation

The implementation of a B-tree is structured around two main classes: BTreeNode and BTree.

1. BTreeNode Class

The BTreeNode class represents a node in the B-tree. Each node contains:

  • keys: A list that stores the keys in the node, kept in sorted order.
  • children: A list of pointers to child nodes. This list is empty for leaf nodes.
  • leaf: A boolean flag that indicates whether the node is a leaf.

2. BTree Class

The BTree class represents the B-tree itself and provides methods for inserting keys, searching for keys, and managing the tree’s structure. The key methods include:

  • search(self, k, x=None): Searches for a key k starting from the node x. It returns the node and index where the key is found, or None if the key is not present.
  • insert(self, k): Inserts a new key k into the B-tree. If the root is full, the tree grows in height by splitting the root.
  • split_child(self, x, i): Splits a full child node of x at index i. This is used to ensure nodes do not exceed the maximum number of keys.
  • insert_non_full(self, x, k): Handles the insertion of a key into a node that is not full. If necessary, it recursively splits child nodes that are full.

Usage Example


# Example usage of the BTree

# Create a B-tree with a minimum degree of 3
btree = BTree(3)

# Insert some keys into the B-tree
keys = [10, 20, 5, 6, 12, 30, 7, 17]
for key in keys:
btree.insert(key)

# Search for a key in the B-tree
result = btree.search(6)
if result:
node, index = result
print(f"Key 6 found in node with keys: {node.keys}")
else:
print("Key 6 not found in the B-tree")

# Output should show that key 6 is found in the node

This example demonstrates how to create a B-tree with a minimum degree of 3, insert several keys into the tree, and search for a specific key. The output indicates whether the key is found and, if so, the node in which it resides.


By Aditya Bhuyan

I work as a cloud specialist. In addition to being an architect and SRE specialist, I work as a cloud engineer and developer. I have assisted my clients in converting their antiquated programmes into contemporary microservices that operate on various cloud computing platforms such as AWS, GCP, Azure, or VMware Tanzu, as well as orchestration systems such as Docker Swarm or Kubernetes. For over twenty years, I have been employed in the IT sector as a Java developer, J2EE architect, scrum master, and instructor. I write about Cloud Native and Cloud often. Bangalore, India is where my family and I call home. I maintain my physical and mental fitness by doing a lot of yoga and meditation.

Leave a Reply

Your email address will not be published. Required fields are marked *

error

Enjoy this blog? Please spread the word :)