This commit is contained in:
Oliver Hofmann 2025-05-13 12:58:04 +02:00
parent 63a3460c21
commit 27ca711383
2 changed files with 149 additions and 0 deletions

View File

@ -0,0 +1,120 @@
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)}")

View File

@ -0,0 +1,29 @@
from utils.literal import Literal
from utils.memory_cell import MemoryCell
from utils.memory_array import MemoryArray
class BTreeNode(MemoryCell):
def __init__(self, m: int):
super().__init__()
self.m = m
self.n = 0
self.leaf = True
self.value = MemoryArray(Literal(2 * m - 1))
self.children = [None] * (2 * m)
self.loaded_count = 0
self.saved_count = 0
def reset_counters(self):
super().reset_counters()
self.loaded_count = 0
self.saved_count = 0
def load(self):
self.loaded_count += 1
def save(self):
self.saved_count += 1
def __str__(self):
return "(" + " ".join([str(self.value[Literal(i)]) for i in range(self.n)]) + ")"