diff --git a/vorlesung/L05_binaere_baeume/avl_tree.py b/vorlesung/L05_binaere_baeume/avl_tree.py index 4a594bd..d906050 100644 --- a/vorlesung/L05_binaere_baeume/avl_tree.py +++ b/vorlesung/L05_binaere_baeume/avl_tree.py @@ -1,6 +1,6 @@ from vorlesung.L05_binaere_baeume.avl_tree_node import AVLTreeNode from vorlesung.L05_binaere_baeume.bin_tree import BinaryTree - +import logging class AVLTree(BinaryTree): @@ -27,15 +27,26 @@ class AVLTree(BinaryTree): self.balance(node.parent) else: self.root = node - # self.check_circle(self.root) def insert(self, value): + insert_generator = self.insert_stepwise(value) + node, parent = None, None + while True: + try: + node, parent = next(insert_generator) + except StopIteration: + break + return node, parent + + def insert_stepwise(self, value): node, parent = super().insert(value) + yield None, None node.parent = parent if parent: self.balance(parent) return node, parent + def delete(self, value): node, parent = super().delete(value) if node: @@ -43,15 +54,6 @@ class AVLTree(BinaryTree): if parent: self.balance(parent) - def check_circle(self, node: AVLTreeNode, check_nodes = []): - if node is None: - return - if id(node) in check_nodes: - print("Circle detected") - return - self.check_circle(node.left, check_nodes + [id(node)]) - self.check_circle(node.right, check_nodes + [id(node)]) - if __name__ == "__main__": diff --git a/vorlesung/L05_binaere_baeume/avl_tree_game.py b/vorlesung/L05_binaere_baeume/avl_tree_game.py new file mode 100644 index 0000000..d726bb7 --- /dev/null +++ b/vorlesung/L05_binaere_baeume/avl_tree_game.py @@ -0,0 +1,59 @@ +import random +import pygame +from utils.game import Game +from avl_tree import AVLTree + +WHITE = (255, 255, 255) +BLUE = (0, 0, 255) +BLACK = (0, 0, 0) +WIDTH = 800 +HEIGHT = 400 +MARGIN = 20 + +class AVLTreeGame(Game): + + def __init__(self): + super().__init__("AVLTree Game", fps=10, size=(WIDTH, HEIGHT)) + random.seed() + self.z = list(range(1, 501)) + random.shuffle(self.z) + self.finished = False + self.tree = AVLTree() + self.tree.get_height = lambda node: 0 if node is None else 1 + max(self.tree.get_height(node.left), self.tree.get_height(node.right)) + self.height = self.tree.get_height(self.tree.root) + self.generator = None + + def update_game(self): + if not self.finished: + if self.generator is None: + self.generator = self.tree.insert_stepwise(self.z.pop()) + try: + next(self.generator) + except StopIteration: + self.generator = None + if self.generator is None and len(self.z) == 0: + self.finished = True + self.height = self.tree.get_height(self.tree.root) + return True + + def draw_game(self): + self.screen.fill(WHITE) + if self.height > 0: + self.draw_tree(self.tree.root, WIDTH // 2, MARGIN, WIDTH // 4 - MARGIN) + super().draw_game() + + def draw_tree(self, node, x, y, x_offset): + y_offset = (HEIGHT - (2 * MARGIN)) / self.height + if node is not None: + pygame.draw.circle(self.screen, BLUE, (x, y), 2) + if node.left is not None: + pygame.draw.line(self.screen, BLACK, (x, y), (x - x_offset, y + y_offset)) + self.draw_tree(node.left, x - x_offset, y + y_offset, x_offset // 2) + if node.right is not None: + pygame.draw.line(self.screen, BLACK, (x, y), (x + x_offset, y + y_offset)) + self.draw_tree(node.right, x + x_offset, y + y_offset, x_offset // 2) + +if __name__ == "__main__": + tree_game = AVLTreeGame() + tree_game.run() + diff --git a/vorlesung/L05_binaere_baeume/bin_tree_game.py b/vorlesung/L05_binaere_baeume/bin_tree_game.py new file mode 100644 index 0000000..3aef208 --- /dev/null +++ b/vorlesung/L05_binaere_baeume/bin_tree_game.py @@ -0,0 +1,54 @@ +import random +import pygame +from utils.game import Game +from bin_tree import BinaryTree + +WHITE = (255, 255, 255) +BLUE = (0, 0, 255) +BLACK = (0, 0, 0) +WIDTH = 800 +HEIGHT = 400 +MARGIN = 20 + +class BinTreeGame(Game): + + def __init__(self): + super().__init__("BinTree Game", fps=10, size=(WIDTH, HEIGHT)) + random.seed() + self.z = list(range(1, 101)) + random.shuffle(self.z) + self.finished = False + self.tree = BinaryTree() + self.tree.get_height = lambda node: 0 if node is None else 1 + max(self.tree.get_height(node.left), self.tree.get_height(node.right)) + self.height = self.tree.get_height(self.tree.root) + + def update_game(self): + if not self.finished: + i = self.z.pop() + self.tree.insert(i) + self.height = self.tree.get_height(self.tree.root) + if len(self.z) == 0: + self.finished = True + return True + + def draw_game(self): + self.screen.fill(WHITE) + if self.height > 0: + self.draw_tree(self.tree.root, WIDTH // 2, MARGIN, WIDTH // 4 - MARGIN) + super().draw_game() + + def draw_tree(self, node, x, y, x_offset): + y_offset = (HEIGHT - (2 * MARGIN)) / self.height + if node is not None: + pygame.draw.circle(self.screen, BLUE, (x, y), 2) + if node.left is not None: + pygame.draw.line(self.screen, BLACK, (x, y), (x - x_offset, y + y_offset)) + self.draw_tree(node.left, x - x_offset, y + y_offset, x_offset // 2) + if node.right is not None: + pygame.draw.line(self.screen, BLACK, (x, y), (x + x_offset, y + y_offset)) + self.draw_tree(node.right, x + x_offset, y + y_offset, x_offset // 2) + +if __name__ == "__main__": + tree_game = BinTreeGame() + tree_game.run() +