Skip to content

Commit

Permalink
Added btree and test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
Richajaishwal0 committed Nov 5, 2024
1 parent fb79fad commit b45d07c
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 0 deletions.
50 changes: 50 additions & 0 deletions Tests/algorithms/test_btree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import unittest
from pysnippets.algorithms.btree import BTree # Adjust the import path as needed

class TestBTree(unittest.TestCase):

def setUp(self):
# Set up a B-Tree with a minimum degree of 3 for testing
self.t = 3
self.btree = BTree(self.t)
# Data for testing
self.keys_to_insert = [10, 20, 5, 6, 12, 30, 7, 17]

def test_insert_and_traverse(self):
# Insert keys into the B-Tree
for key in self.keys_to_insert:
self.btree.insert(key)

# Capture the output of the traversal
import io
import sys
output = io.StringIO()
sys.stdout = output
self.btree.traverse()
sys.stdout = sys.__stdout__ # Reset redirect

# Expected traversal order
expected_output = "5 6 7 10 12 17 20 30"
self.assertEqual(output.getvalue().strip(), expected_output)

def test_search_existing_key(self):
# Insert keys into the B-Tree
for key in self.keys_to_insert:
self.btree.insert(key)

# Search for an existing key
result = self.btree.search(12)
self.assertIsNotNone(result)
self.assertIn(12, result.keys)

def test_search_non_existing_key(self):
# Insert keys into the B-Tree
for key in self.keys_to_insert:
self.btree.insert(key)

# Search for a non-existing key
result = self.btree.search(99)
self.assertIsNone(result)

if __name__ == '__main__':
unittest.main()
96 changes: 96 additions & 0 deletions pysnippets/algorithms/btree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
class BTreeNode:
def __init__(self, t, leaf=False):
self.t = t # Minimum degree
self.keys = [] # List of keys
self.children = [] # List of child pointers
self.leaf = leaf # Boolean to indicate if the node is a leaf

# Function to traverse all nodes in a subtree rooted with this node
def traverse(self):
for i in range(len(self.keys)):
if not self.leaf:
self.children[i].traverse()
print(self.keys[i], end=" ")
if not self.leaf:
self.children[len(self.keys)].traverse()

# Function to search a key in the subtree rooted with this node
def search(self, k):
i = 0
while i < len(self.keys) and k > self.keys[i]:
i += 1

if i < len(self.keys) and self.keys[i] == k:
return self

if self.leaf:
return None

return self.children[i].search(k)


class BTree:
def __init__(self, t):
self.root = None
self.t = t # Minimum degree

# Function to traverse the tree
def traverse(self):
if self.root is not None:
self.root.traverse()

# Function to search a key in this tree
def search(self, k):
return self.root.search(k) if self.root else None

# Function to insert a new key in this tree
def insert(self, k):
if self.root is None:
self.root = BTreeNode(self.t, leaf=True)
self.root.keys = [k]
else:
if len(self.root.keys) == 2 * self.t - 1:
s = BTreeNode(self.t, leaf=False)
s.children.insert(0, self.root)
self.split_child(s, 0)
i = 0
if s.keys[0] < k:
i += 1
self.insert_non_full(s.children[i], k)
self.root = s
else:
self.insert_non_full(self.root, k)

# Function to split the child of a node
def split_child(self, parent, i):
t = self.t
y = parent.children[i]
z = BTreeNode(t, y.leaf)
parent.children.insert(i + 1, z)
parent.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]

# Function to insert a new key into a non-full node
def insert_non_full(self, node, k):
i = len(node.keys) - 1
if node.leaf:
node.keys.append(None)
while i >= 0 and k < node.keys[i]:
node.keys[i + 1] = node.keys[i]
i -= 1
node.keys[i + 1] = k
else:
while i >= 0 and k < node.keys[i]:
i -= 1
i += 1
if len(node.children[i].keys) == 2 * self.t - 1:
self.split_child(node, i)
if k > node.keys[i]:
i += 1
self.insert_non_full(node.children[i], k)

0 comments on commit b45d07c

Please sign in to comment.