from SoSe24.algodat.foundation import AlgoDatArray, AlgoDatValue, read_int_sequence from time import perf_counter as pfc class BinTreeNode: def __init__(self, value: AlgoDatValue): self.value = value self.left = None self.right = None def __str__(self): return f"{self.value}" def height(self) -> int: left_height = self.left.height() if self.left else 0 right_height = self.right.height() if self.right else 0 return 1 + max(left_height, right_height) class BinTree: def __init__(self): self.root = None def new_node(self, value: AlgoDatValue) -> BinTreeNode: return BinTreeNode(value) def insert(self, value: AlgoDatValue) -> (BinTreeNode, BinTreeNode): if not self.root: self.root = self.new_node(value) return self.root, None current = self.root while True: if value < current.value: if current.left: current = current.left else: current.left = self.new_node(value) return current.left, current elif value >= current.value: if current.right: current = current.right else: current.right = self.new_node(value) return current.right, current else: return None, None def search(self, value: AlgoDatValue) -> BinTreeNode: current = self.root while current: if value < current.value: current = current.left elif value > current.value: current = current.right else: return current return None def delete(self, value: AlgoDatValue): parent = None current = self.root while current: if value < current.value: parent = current current = current.left elif value >= current.value: parent = current current = current.right else: break else: return if current.left and current.right: parent = current successor = current.right while successor.left: parent = successor successor = successor.left current.value.value = successor.value.value current = successor if current.left: child = current.left else: child = current.right if not parent: self.root = child return child, None elif parent.left == current: parent.left = child return child, parent else: parent.right = child return child, parent def walk(self): # in-order print("[ ", end="") self.walk_recursive(self.root, 0, 0) print(" ]") def graph_walk(self): self.leaf_counter = 0 with open("../../graph.gv", "w") as file: file.write("digraph BST {\n") file.write(" node [fontname=\"Arial\"];\n") self.graph_walk_recursive(self.root, file) file.write("}") def graph_walk_recursive(self, current, file): if current is not None: if current.left: file.write(f"{current.value} -> {current.left.value}; \n") self.graph_walk_recursive(current.left, file) else: file.write(f"left{self.leaf_counter} [shape=point]; \n") file.write(f"{current.value} -> left{self.leaf_counter}; \n") self.leaf_counter += 1 if current.right: file.write(f"{current.value} -> {current.right.value}; \n") self.graph_walk_recursive(current.right, file) else: file.write(f"right{self.leaf_counter} [shape=point]; \n") file.write(f"{current.value} -> right{self.leaf_counter}; \n") self.leaf_counter += 1 def tree_walk(self): self.walk_recursive(self.root, 0, 1) def walk_recursive(self, node: BinTreeNode, level = 0, increase = 1): if node: if increase >= 1: end = "\n" else: end = " " self.walk_recursive(node.left, level+increase, increase) print(" "*level*3 + str(node.value), end=end) self.walk_recursive(node.right, level+increase, increase) def levelwalk(self): if self.root is None: return queue = [self.root] while queue: current = queue.pop(0) print(current.value, end=" ") if current.left: queue.append(current.left) if current.right: queue.append(current.right) print() if __name__ == "__main__": z = read_int_sequence("../../seq0.txt") print(z, len(z)) start = pfc() tree = BinTree() for i in z: tree.insert(i) tree.walk() tree.tree_walk() tree.levelwalk() tree.delete(AlgoDatValue(46)) tree.graph_walk() print(f"Dauer: {pfc() - start:.4f}s") AlgoDatValue.summary()