class BTreeNode:
def __init__(self, t, leaf=False):
self.t = t # Minimum degree
self.keys = []
self.children = []
self.leaf = leaf
def insert_non_full(self, key):
i = len(self.keys) - 1
if self.leaf:
self.keys.append(None)
while i >= 0 and key < self.keys[i]:
self.keys[i + 1] = self.keys[i]
i -= 1
self.keys[i + 1] = key
else:
while i >= 0 and key < self.keys[i]:
i -= 1
i += 1
if len(self.children[i].keys) == 2 * self.t - 1:
self.split_child(i)
if key > self.keys[i]:
i += 1
self.children[i].insert_non_full(key)
def split_child(self, i):
t = self.t
y = self.children[i]
z = BTreeNode(t, y.leaf)
z.keys = y.keys[t:]
y.keys = y.keys[:t - 1]
if not y.leaf:
z.children = y.children[t:]
y.children = y.children[:t]
self.children.insert(i + 1, z)
self.keys.insert(i, y.keys.pop())
class BTree:
def __init__(self, t):
self.root = BTreeNode(t, True)
self.t = t
def insert(self, key):
root = self.root
if len(root.keys) == 2 * self.t - 1:
s = BTreeNode(self.t)
s.children.insert(0, root)
s.leaf = False
s.split_child(0)
i = 0
if s.keys[0] < key:
i += 1
s.children[i].insert_non_full(key)
self.root = s
else:
root.insert_non_full(key)
def traverse(self, node=None):
if node is None:
node = self.root
for i in range(len(node.keys)):
if not node.leaf:
self.traverse(node.children[i])
print(node.keys[i], end=' ')
if not node.leaf:
self.traverse(node.children[len(node.keys)])
# Example usage
btree = BTree(2)
for key in [10, 20, 5, 6, 12, 30, 7, 17]:
btree.insert(key)
btree.traverse()