123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- 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()
|