Umstellen der Auswertungslogik
This commit is contained in:
@@ -1,26 +1,22 @@
|
||||
from utils.memory_manager import MemoryManager
|
||||
from utils.memory_array import MemoryArray
|
||||
from utils.literal import Literal
|
||||
from utils.algo_context import AlgoContext
|
||||
from utils.algo_array import Array
|
||||
from vorlesung.L05_binaere_baeume.avl_tree import AVLTree
|
||||
|
||||
|
||||
def analyze_complexity(sizes):
|
||||
"""
|
||||
Analysiert die Komplexität
|
||||
|
||||
:param sizes: Eine Liste von Eingabegrößen für die Analyse.
|
||||
"""
|
||||
ctx = AlgoContext()
|
||||
for size in sizes:
|
||||
MemoryManager.purge() # Speicher zurücksetzen
|
||||
tree = AVLTree()
|
||||
random_array = MemoryArray.create_random_array(size, -100, 100)
|
||||
for i in range(size-1):
|
||||
tree.insert(int(random_array[Literal(i)]))
|
||||
MemoryManager.reset()
|
||||
tree.insert(int(random_array[Literal(size-1)]))
|
||||
MemoryManager.save_stats(size)
|
||||
z = Array.random(size, -100, 100, ctx)
|
||||
tree = AVLTree(ctx)
|
||||
for i in range(size - 1):
|
||||
tree.insert(z[i].value)
|
||||
ctx.reset()
|
||||
tree.insert(z[size - 1].value)
|
||||
ctx.save_stats(size)
|
||||
|
||||
ctx.plot_stats(["comparisons"])
|
||||
|
||||
MemoryManager.plot_stats(["cells", "compares"])
|
||||
|
||||
if __name__ == "__main__":
|
||||
sizes = range(1, 1001, 2)
|
||||
analyze_complexity(sizes)
|
||||
analyze_complexity(sizes)
|
||||
|
||||
@@ -1,26 +1,22 @@
|
||||
from utils.memory_manager import MemoryManager
|
||||
from utils.memory_array import MemoryArray
|
||||
from utils.literal import Literal
|
||||
from utils.algo_context import AlgoContext
|
||||
from utils.algo_array import Array
|
||||
from vorlesung.L05_binaere_baeume.bin_tree import BinaryTree
|
||||
|
||||
|
||||
def analyze_complexity(sizes):
|
||||
"""
|
||||
Analysiert die Komplexität
|
||||
|
||||
:param sizes: Eine Liste von Eingabegrößen für die Analyse.
|
||||
"""
|
||||
ctx = AlgoContext()
|
||||
for size in sizes:
|
||||
MemoryManager.purge() # Speicher zurücksetzen
|
||||
tree = BinaryTree()
|
||||
random_array = MemoryArray.create_random_array(size, -100, 100)
|
||||
for i in range(size-1):
|
||||
tree.insert(int(random_array[Literal(i)]))
|
||||
MemoryManager.reset()
|
||||
tree.insert(int(random_array[Literal(size-1)]))
|
||||
MemoryManager.save_stats(size)
|
||||
z = Array.random(size, -100, 100, ctx)
|
||||
tree = BinaryTree(ctx)
|
||||
for i in range(size - 1):
|
||||
tree.insert(z[i].value)
|
||||
ctx.reset()
|
||||
tree.insert(z[size - 1].value)
|
||||
ctx.save_stats(size)
|
||||
|
||||
ctx.plot_stats(["comparisons"])
|
||||
|
||||
MemoryManager.plot_stats(["cells", "compares"])
|
||||
|
||||
if __name__ == "__main__":
|
||||
sizes = range(1, 1001, 2)
|
||||
analyze_complexity(sizes)
|
||||
analyze_complexity(sizes)
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
from utils.memory_array import MemoryArray
|
||||
from vorlesung.L05_binaere_baeume.avl_tree_node import AVLTreeNode
|
||||
from vorlesung.L05_binaere_baeume.bin_tree import BinaryTree
|
||||
import logging
|
||||
from utils.algo_context import AlgoContext
|
||||
from utils.algo_array import Array
|
||||
|
||||
|
||||
class AVLTree(BinaryTree):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
def __init__(self, ctx: AlgoContext):
|
||||
super().__init__(ctx)
|
||||
|
||||
def new_node(self, value):
|
||||
return AVLTreeNode(value)
|
||||
|
||||
return AVLTreeNode(value, self.ctx)
|
||||
|
||||
def balance(self, node: AVLTreeNode):
|
||||
node.update_balance()
|
||||
@@ -47,7 +47,6 @@ class AVLTree(BinaryTree):
|
||||
self.balance(parent)
|
||||
return node, parent
|
||||
|
||||
|
||||
def delete(self, value):
|
||||
node, parent = super().delete(value)
|
||||
if node:
|
||||
@@ -58,37 +57,25 @@ class AVLTree(BinaryTree):
|
||||
def graph_filename(self):
|
||||
return "AVLTree"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
ctx = AlgoContext()
|
||||
tree = AVLTree(ctx)
|
||||
|
||||
values = Array.from_file("data/seq2.txt", ctx)
|
||||
for cell in values:
|
||||
tree.insert(cell.value)
|
||||
|
||||
def print_node(node, indent=0, level=0):
|
||||
print((indent * 3) * " ", node.value)
|
||||
|
||||
tree = AVLTree()
|
||||
#values = [5, 3, 7, 2, 4, 6, 5, 8]
|
||||
values = MemoryArray.create_array_from_file("data/seq2.txt")
|
||||
|
||||
for value in values:
|
||||
tree.insert(value)
|
||||
|
||||
|
||||
print("In-order traversal:")
|
||||
tree.in_order_traversal(print_node)
|
||||
print("\nLevel-order traversal:")
|
||||
tree.level_order_traversal(print_node)
|
||||
print("\nTree structure traversal:")
|
||||
tree.tree_structure_traversal(print_node)
|
||||
print("\nGraph traversal:")
|
||||
tree.graph_traversal()
|
||||
|
||||
tree.insert(9)
|
||||
tree.graph_traversal()
|
||||
|
||||
print("\nDeleting 5:")
|
||||
tree.delete(5)
|
||||
|
||||
print("In-order traversal after deletion:")
|
||||
tree.in_order_traversal(print_node)
|
||||
print("\nLevel-order traversal after deletion:")
|
||||
tree.level_order_traversal(print_node)
|
||||
print("\nTree structure traversal after deletion:")
|
||||
tree.tree_structure_traversal(print_node)
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import random
|
||||
import pygame
|
||||
from utils.game import Game
|
||||
from utils.algo_context import AlgoContext
|
||||
from avl_tree import AVLTree
|
||||
|
||||
WHITE = (255, 255, 255)
|
||||
BLUE = (0, 0, 255)
|
||||
BLACK = (0, 0, 0)
|
||||
WIDTH = 800
|
||||
HEIGHT = 400
|
||||
MARGIN = 20
|
||||
BLUE = (0, 0, 255)
|
||||
BLACK = (0, 0, 0)
|
||||
WIDTH, HEIGHT, MARGIN = 800, 400, 20
|
||||
|
||||
|
||||
class AVLTreeGame(Game):
|
||||
|
||||
@@ -18,8 +18,12 @@ class AVLTreeGame(Game):
|
||||
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.ctx = AlgoContext()
|
||||
self.tree = AVLTree(self.ctx)
|
||||
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
|
||||
|
||||
@@ -43,7 +47,7 @@ class AVLTreeGame(Game):
|
||||
super().draw_game()
|
||||
|
||||
def draw_tree(self, node, x, y, x_offset):
|
||||
y_offset = (HEIGHT - (2 * MARGIN)) / self.height
|
||||
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:
|
||||
@@ -53,7 +57,7 @@ class AVLTreeGame(Game):
|
||||
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()
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
from vorlesung.L05_binaere_baeume.bin_tree_node import BinaryTreeNode
|
||||
from utils.algo_context import AlgoContext
|
||||
|
||||
|
||||
class AVLTreeNode(BinaryTreeNode):
|
||||
def __init__(self, value):
|
||||
super().__init__(value)
|
||||
|
||||
def __init__(self, value, ctx: AlgoContext):
|
||||
super().__init__(value, ctx)
|
||||
self.parent = None
|
||||
self.balance = 0
|
||||
self.balance = 0 # plain int – Metadaten, kein Zähler
|
||||
|
||||
def __repr__(self):
|
||||
return f"TreeNode(id={id(self)} value={self.value}, left={self.left}, right={self.right})"
|
||||
@@ -13,7 +16,7 @@ class AVLTreeNode(BinaryTreeNode):
|
||||
dot.node(str(id(self)), label=str(self.value), pos=f"{col},{-row}!", xlabel=str(self.balance))
|
||||
|
||||
def update_balance(self):
|
||||
left_height = self.left.height() if self.left else 0
|
||||
left_height = self.left.height() if self.left else 0
|
||||
right_height = self.right.height() if self.right else 0
|
||||
self.balance = right_height - left_height
|
||||
|
||||
@@ -58,4 +61,3 @@ class AVLTreeNode(BinaryTreeNode):
|
||||
def left_right_rotate(self):
|
||||
self.left = self.left.left_rotate()
|
||||
return self.right_rotate()
|
||||
|
||||
|
||||
@@ -1,61 +1,53 @@
|
||||
import random
|
||||
|
||||
from utils.memory_array import MemoryArray
|
||||
from utils.memory_cell import MemoryCell
|
||||
from utils.memory_manager import MemoryManager
|
||||
from utils.memory_range import mrange
|
||||
from utils.literal import Literal
|
||||
from utils.algo_context import AlgoContext
|
||||
from utils.algo_array import Array
|
||||
from utils.algo_int import Int
|
||||
|
||||
|
||||
def binary_search(z: MemoryArray, s: MemoryCell, l: Literal = None, r: Literal = None):
|
||||
def binary_search(z: Array, s: Int, l: int = None, r: int = None):
|
||||
"""
|
||||
Perform a binary search on the sorted array z for the value x.
|
||||
Binäre Suche auf dem sortierten Array z nach dem Wert s.
|
||||
|
||||
l, r – 0-basierte Grenzen (plain int, optional).
|
||||
Gibt den Index als plain int zurück, oder None wenn nicht gefunden.
|
||||
"""
|
||||
if l is None:
|
||||
l = Literal(0)
|
||||
l = 0
|
||||
if r is None:
|
||||
r = Literal(z.length().pred())
|
||||
r = len(z) - 1
|
||||
if l > r:
|
||||
return None
|
||||
with MemoryCell(l) as m:
|
||||
m += r
|
||||
m //= Literal(2)
|
||||
if s < z[m]:
|
||||
return binary_search(z, s, l, m.pred())
|
||||
elif s > z[m]:
|
||||
return binary_search(z, s, m.succ(), r)
|
||||
else:
|
||||
return m
|
||||
|
||||
m = Int((l + r) // 2, s._ctx)
|
||||
if s < z[m]:
|
||||
return binary_search(z, s, l, int(m) - 1)
|
||||
elif s > z[m]:
|
||||
return binary_search(z, s, int(m) + 1, r)
|
||||
else:
|
||||
return int(m)
|
||||
|
||||
|
||||
def analyze_complexity(sizes):
|
||||
"""
|
||||
Analysiert die Komplexität
|
||||
|
||||
:param sizes: Eine Liste von Eingabegrößen für die Analyse.
|
||||
"""
|
||||
ctx = AlgoContext()
|
||||
for size in sizes:
|
||||
MemoryManager.purge() # Speicher zurücksetzen
|
||||
random_array = MemoryArray.create_sorted_array(size)
|
||||
search_value = random.randint(-100, 100)
|
||||
binary_search(random_array, MemoryCell(search_value))
|
||||
MemoryManager.save_stats(size)
|
||||
|
||||
MemoryManager.plot_stats(["cells", "compares", "adds"])
|
||||
|
||||
ctx.reset()
|
||||
z = Array.sorted(size, ctx)
|
||||
search_value = Int(random.randint(0, size - 1), ctx)
|
||||
binary_search(z, search_value)
|
||||
ctx.save_stats(size)
|
||||
|
||||
ctx.plot_stats(["comparisons", "additions"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Example usage
|
||||
arr = MemoryArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
|
||||
search_value = MemoryCell(8)
|
||||
result = binary_search(arr, search_value)
|
||||
ctx = AlgoContext()
|
||||
arr = Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ctx)
|
||||
s = Int(8, ctx)
|
||||
result = binary_search(arr, s)
|
||||
if result is not None:
|
||||
print(f"Value {search_value} found at index {result}.")
|
||||
print(f"Value {s} found at index {result}.")
|
||||
else:
|
||||
print(f"Value {search_value} not found in the array.")
|
||||
|
||||
print(f"Value {s} not found.")
|
||||
|
||||
sizes = range(1, 1001, 2)
|
||||
analyze_complexity(sizes)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from vorlesung.L05_binaere_baeume.bin_tree_node import BinaryTreeNode
|
||||
from utils.algo_context import AlgoContext
|
||||
from utils.project_dir import get_path
|
||||
from datetime import datetime
|
||||
import graphviz
|
||||
@@ -6,12 +7,13 @@ import graphviz
|
||||
|
||||
class BinaryTree:
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, ctx: AlgoContext):
|
||||
self.root = None
|
||||
self.size = 0
|
||||
self.ctx = ctx
|
||||
|
||||
def new_node(self, value):
|
||||
return BinaryTreeNode(value)
|
||||
return BinaryTreeNode(value, self.ctx)
|
||||
|
||||
def insert(self, value):
|
||||
self.size += 1
|
||||
@@ -50,9 +52,6 @@ class BinaryTree:
|
||||
return None
|
||||
|
||||
def delete(self, value):
|
||||
# Der Wert wird im Baum gesucht und der erste Treffer gelöscht
|
||||
# Rückgabe falls der Wert gefunden wird:
|
||||
# der Knoten, der den zu löschenden Knoten ersetzt und der Elternknoten des gelöschten Knotens
|
||||
parent = None
|
||||
current = self.root
|
||||
value = self.new_node(value)
|
||||
@@ -64,38 +63,25 @@ class BinaryTree:
|
||||
parent = current
|
||||
current = current.right
|
||||
else:
|
||||
# Knoten gefunden
|
||||
break
|
||||
else:
|
||||
# Wert nicht gefunden
|
||||
return None, None
|
||||
return self.delete_node(current, parent)
|
||||
|
||||
def delete_node(self, current, parent):
|
||||
# Der übergebene Knoten wird
|
||||
# Rückgabe ist ein Tupel:
|
||||
# der Knoten, der den zu löschenden Knoten ersetzt und der Elternknoten des gelöschten Knotens
|
||||
self.size -= 1
|
||||
# Fall 3: Es gibt zwei Kinder: wir suchen den Nachfolger
|
||||
# Fall 3: zwei Kinder → Nachfolger suchen
|
||||
if current.left and current.right:
|
||||
parent = current
|
||||
successor = current.right
|
||||
while successor.left:
|
||||
parent = successor
|
||||
successor = successor.left
|
||||
# Wert des Nachfolgers wird in den Knoten geschrieben, der gelöscht werden soll
|
||||
current.value = successor.value
|
||||
# Ab jetzt muss successor gelöscht werden; parent ist bereits richtig gesetzt
|
||||
current.set(successor) # Wert kopieren (1 read + 1 write)
|
||||
current = successor
|
||||
|
||||
# Ermitteln des einen Kindes (falls es eines gibt), sonst None
|
||||
# Das eine Kind ist der Ersatz für den Knoten, der gelöscht werden soll
|
||||
if current.left:
|
||||
child = current.left
|
||||
else:
|
||||
child = current.right
|
||||
child = current.left if current.left else current.right
|
||||
|
||||
# Falls es keinen Elternknoten gibt, ist der Ersatzknoten die Wurzel
|
||||
if not parent:
|
||||
self.root = child
|
||||
return child, None
|
||||
@@ -106,17 +92,13 @@ class BinaryTree:
|
||||
parent.right = child
|
||||
return child, parent
|
||||
|
||||
|
||||
def in_order_traversal(self, callback):
|
||||
|
||||
def in_order_traversal_recursive(callback, current):
|
||||
def _rec(callback, current):
|
||||
if current is not None:
|
||||
in_order_traversal_recursive(callback, current.left)
|
||||
_rec(callback, current.left)
|
||||
callback(current)
|
||||
in_order_traversal_recursive(callback, current.right)
|
||||
|
||||
in_order_traversal_recursive(callback, self.root)
|
||||
|
||||
_rec(callback, current.right)
|
||||
_rec(callback, self.root)
|
||||
|
||||
def level_order_traversal(self, callback):
|
||||
if self.root is None:
|
||||
@@ -125,23 +107,19 @@ class BinaryTree:
|
||||
while queue:
|
||||
current, level = queue.pop(0)
|
||||
callback(current, level)
|
||||
if current.left is not None:
|
||||
queue.append((current.left, level + 1))
|
||||
if current.right is not None:
|
||||
queue.append((current.right, level + 1))
|
||||
if current.left is not None: queue.append((current.left, level + 1))
|
||||
if current.right is not None: queue.append((current.right, level + 1))
|
||||
|
||||
def tree_structure_traversal(self, callback):
|
||||
|
||||
def tree_structure_traversal_recursive(callback, current, level):
|
||||
def _rec(callback, current, level):
|
||||
nonlocal line
|
||||
if current:
|
||||
tree_structure_traversal_recursive(callback, current.left, level + 1)
|
||||
_rec(callback, current.left, level + 1)
|
||||
callback(current, level, line)
|
||||
line += 1
|
||||
tree_structure_traversal_recursive(callback, current.right, level + 1)
|
||||
|
||||
_rec(callback, current.right, level + 1)
|
||||
line = 0
|
||||
tree_structure_traversal_recursive(callback, self.root, 0)
|
||||
_rec(callback, self.root, 0)
|
||||
|
||||
def graph_filename(self):
|
||||
return "BinaryTree"
|
||||
@@ -152,55 +130,44 @@ class BinaryTree:
|
||||
if node is not None:
|
||||
node.graphviz_rep(level, line, dot)
|
||||
|
||||
def graph_traversal_recursive(current):
|
||||
def _rec(current):
|
||||
nonlocal dot
|
||||
if current is not None:
|
||||
if current.left:
|
||||
dot.edge(str(id(current)), str(id(current.left)))
|
||||
graph_traversal_recursive(current.left)
|
||||
_rec(current.left)
|
||||
if current.right:
|
||||
dot.edge(str(id(current)), str(id(current.right)))
|
||||
graph_traversal_recursive(current.right)
|
||||
_rec(current.right)
|
||||
|
||||
dot = graphviz.Digraph( name="BinaryTree",
|
||||
engine="neato",
|
||||
node_attr={"shape": "circle", "fontname": "Arial"},
|
||||
format="pdf" )
|
||||
dot = graphviz.Digraph(
|
||||
name="BinaryTree",
|
||||
engine="neato",
|
||||
node_attr={"shape": "circle", "fontname": "Arial"},
|
||||
format="pdf")
|
||||
self.tree_structure_traversal(define_node)
|
||||
graph_traversal_recursive(self.root)
|
||||
_rec(self.root)
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
filename = f"{self.graph_filename()}_{timestamp}.gv"
|
||||
filename = get_path(filename)
|
||||
dot.render(filename)
|
||||
dot.render(get_path(f"{self.graph_filename()}_{timestamp}.gv"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
tree = BinaryTree()
|
||||
values = [5, 3, 7, 2, 4, 6, 5, 8]
|
||||
|
||||
for value in values:
|
||||
tree.insert(value)
|
||||
ctx = AlgoContext()
|
||||
tree = BinaryTree(ctx)
|
||||
for v in [5, 3, 7, 2, 4, 6, 5, 8]:
|
||||
tree.insert(v)
|
||||
|
||||
def print_node(node, indent=0, line=None):
|
||||
print((indent * 3) * " ", node.value)
|
||||
|
||||
|
||||
print("In-order traversal:")
|
||||
tree.in_order_traversal(print_node)
|
||||
print("\nLevel-order traversal:")
|
||||
tree.level_order_traversal(print_node)
|
||||
print("\nTree structure traversal:")
|
||||
tree.tree_structure_traversal(print_node)
|
||||
print("\nGraph traversal:")
|
||||
tree.graph_traversal()
|
||||
|
||||
print("\nDeleting 5:")
|
||||
tree.delete(5)
|
||||
|
||||
print("In-order traversal after deletion:")
|
||||
tree.in_order_traversal(print_node)
|
||||
print("\nLevel-order traversal after deletion:")
|
||||
tree.level_order_traversal(print_node)
|
||||
print("\nTree structure traversal after deletion:")
|
||||
tree.tree_structure_traversal(print_node)
|
||||
|
||||
|
||||
print("\n", ctx)
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import random
|
||||
import pygame
|
||||
from utils.game import Game
|
||||
from utils.algo_context import AlgoContext
|
||||
from bin_tree import BinaryTree
|
||||
|
||||
WHITE = (255, 255, 255)
|
||||
BLUE = (0, 0, 255)
|
||||
BLACK = (0, 0, 0)
|
||||
WIDTH = 800
|
||||
HEIGHT = 400
|
||||
MARGIN = 20
|
||||
BLUE = (0, 0, 255)
|
||||
BLACK = (0, 0, 0)
|
||||
WIDTH, HEIGHT, MARGIN = 800, 400, 20
|
||||
|
||||
|
||||
class BinTreeGame(Game):
|
||||
|
||||
@@ -18,14 +18,17 @@ class BinTreeGame(Game):
|
||||
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.ctx = AlgoContext()
|
||||
self.tree = BinaryTree(self.ctx)
|
||||
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.tree.insert(self.z.pop())
|
||||
self.height = self.tree.get_height(self.tree.root)
|
||||
if len(self.z) == 0:
|
||||
self.finished = True
|
||||
@@ -38,7 +41,7 @@ class BinTreeGame(Game):
|
||||
super().draw_game()
|
||||
|
||||
def draw_tree(self, node, x, y, x_offset):
|
||||
y_offset = (HEIGHT - (2 * MARGIN)) / self.height
|
||||
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:
|
||||
@@ -48,7 +51,7 @@ class BinTreeGame(Game):
|
||||
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()
|
||||
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
from utils.memory_cell import MemoryCell
|
||||
from utils.algo_int import Int
|
||||
from utils.algo_context import AlgoContext
|
||||
|
||||
class BinaryTreeNode(MemoryCell):
|
||||
|
||||
def __init__(self, value):
|
||||
super().__init__(value)
|
||||
class BinaryTreeNode(Int):
|
||||
"""
|
||||
Knoten eines binären Suchbaums.
|
||||
|
||||
Erbt von Int – Vergleiche zwischen Knoten werden automatisch im
|
||||
AlgoContext gezählt.
|
||||
"""
|
||||
|
||||
def __init__(self, value, ctx: AlgoContext):
|
||||
super().__init__(value, ctx)
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def height(self):
|
||||
left_height = self.left.height() if self.left else 0
|
||||
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)
|
||||
|
||||
@@ -19,4 +27,4 @@ class BinaryTreeNode(MemoryCell):
|
||||
return str(self.value)
|
||||
|
||||
def graphviz_rep(self, row, col, dot):
|
||||
dot.node(str(id(self)), label=str(self.value), pos=f"{col},{-row}!")
|
||||
dot.node(str(id(self)), label=str(self.value), pos=f"{col},{-row}!")
|
||||
|
||||
Reference in New Issue
Block a user