from utils.literal import Literal from utils.memory_cell import MemoryCell from utils.memory_array import MemoryArray from b_tree_node import BTreeNode class BTree: def __init__(self, m: int): self.m = m self.root = BTreeNode(m) def search(self, value, start: BTreeNode = None) -> BTreeNode | None: if not start: start = self.root start.load() i = 0 if not isinstance(value, MemoryCell): value = MemoryCell(value) while i < start.n and value > start.value[Literal(i)]: i += 1 if i < start.n and value == start.value[Literal(i)]: return start if start.leaf: return None return self.search(value, start.children[i]) def split_child(self, parent: BTreeNode, i: int): child = parent.children[i] child.load() h = BTreeNode(self.m) h.leaf = child.leaf h.n = self.m - 1 for j in range(self.m - 1): h.value[Literal(j)] = child.value[Literal(j + self.m)] if not h.leaf: for j in range(self.m): h.children[j] = child.children[j + self.m] for j in range(self.m, child.n + 1): child.children[j] = None child.n = self.m - 1 child.save() h.save() for j in range(parent.n, i, -1): parent.children[j + 1] = parent.children[j] parent.value[Literal(j)] = parent.value[Literal(j - 1)] parent.children[i + 1] = h parent.value[Literal(i)] = child.value[Literal(self.m - 1)] parent.n += 1 parent.save() def insert(self, value): if not isinstance(value, MemoryCell): value = MemoryCell(value) r = self.root if r.n == 2 * self.m - 1: h = BTreeNode(self.m) self.root = h h.leaf = False h.n = 0 h.children[0] = r self.split_child(h, 0) self.insert_in_node(h, value) else: self.insert_in_node(r, value) def insert_in_node(self, start: BTreeNode, value): start.load() i = start.n if start.leaf: while i >= 1 and value < start.value[Literal(i-1)]: start.value[Literal(i)] = start.value[Literal(i-1)] i -= 1 start.value[Literal(i)].set(value) start.n += 1 start.save() else: j = 0 while j < start.n and value > start.value[Literal(j)]: j += 1 if start.children[j].n == 2 * self.m - 1: self.split_child(start, j) if value > start.value[Literal(j)]: j += 1 self.insert_in_node(start.children[j], value) def traversal(self, callback): def traversal_recursive(node, callback): i = 0 while i < node.n: if not node.leaf: traversal_recursive(node.children[i], callback) callback(node.value[Literal(i)]) i += 1 if not node.leaf: traversal_recursive(node.children[i], callback) traversal_recursive(self.root, callback) def walk(self): def print_key(key): print(key, end=" ") self.traversal(print_key) def height(self, start: BTreeNode = None): if not start: start = self.root if start.leaf: return 0 return 1 + self.height(start.children[0]) if __name__ == "__main__": a = MemoryArray.create_array_from_file("data/seq3.txt") tree = BTree(3) for cell in a: tree.insert(cell) print(f"Height: {tree.height()}") tree.walk() s = tree.search(0) print(f"\nKnoten mit 0: {str(s)}")