AVL implementation

This commit is contained in:
Oliver Hofmann 2025-04-29 18:19:35 +02:00
parent 326286128c
commit ac7068d26c
5 changed files with 200 additions and 0 deletions

View File

@ -0,0 +1,12 @@
from utils.memory_array import MemoryArray
from vorlesung.L05_binaere_baeume.avl_tree import AVLTree
if __name__ == "__main__":
a = MemoryArray.create_array_from_file("data/seq0.txt")
tree = AVLTree()
for cell in a:
tree.insert(int(cell))
tree.graph_traversal()

View File

@ -0,0 +1,12 @@
from utils.memory_array import MemoryArray
from vorlesung.L05_binaere_baeume.bin_tree import BinaryTree
if __name__ == "__main__":
a = MemoryArray.create_array_from_file("data/seq0.txt")
tree = BinaryTree()
for cell in a:
tree.insert(int(cell))
tree.graph_traversal()

View File

@ -0,0 +1,26 @@
from utils.memory_manager import MemoryManager
from utils.memory_array import MemoryArray
from utils.literal import Literal
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.
"""
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)
MemoryManager.plot_stats(["cells", "compares"])
if __name__ == "__main__":
sizes = range(1, 1001, 2)
analyze_complexity(sizes)

View File

@ -0,0 +1,88 @@
from vorlesung.L05_binaere_baeume.avl_tree_node import AVLTreeNode
from vorlesung.L05_binaere_baeume.bin_tree import BinaryTree
class AVLTree(BinaryTree):
def __init__(self):
super().__init__()
def new_node(self, value):
return AVLTreeNode(value)
def balance(self, node: AVLTreeNode):
node.update_balance()
if node.balance == -2:
if node.left.balance <= 0:
node = node.right_rotate()
else:
node = node.left_right_rotate()
elif node.balance == 2:
if node.right.balance >= 0:
node = node.left_rotate()
else:
node = node.right_left_rotate()
if node.parent:
self.balance(node.parent)
else:
self.root = node
# self.check_circle(self.root)
def insert(self, value):
node, parent = super().insert(value)
node.parent = parent
if parent:
self.balance(parent)
return node, parent
def delete(self, value):
node, parent = super().delete(value)
if node:
node.parent = parent
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__":
def print_node(node, indent=0, level=0):
print((indent * 3) * " ", node.value)
tree = AVLTree()
values = [5, 3, 7, 2, 4, 6, 5, 8]
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)

View File

@ -0,0 +1,62 @@
from vorlesung.L05_binaere_baeume.bin_tree_node import BinaryTreeNode
class AVLTreeNode(BinaryTreeNode):
def __init__(self, value):
super().__init__(value)
self.parent = None
self.balance = 0
def __repr__(self):
return f"TreeNode(id={id(self)} value={self.value}, left={self.left}, right={self.right})"
def gv_rep(self, row, col):
"""Returns the graphviz representation of the node."""
return f"{id(self)} [label=\"{self.value}\", pos=\"{col},{-row}!\", xlabel=\"{self.balance}\"];\n"
def update_balance(self):
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
def right_rotate(self):
new_root = self.left
new_root.parent = self.parent
self.left = new_root.right
if self.left:
self.left.parent = self
new_root.right = self
self.parent = new_root
if new_root.parent:
if new_root.parent.left is self:
new_root.parent.left = new_root
else:
new_root.parent.right = new_root
self.update_balance()
new_root.update_balance()
return new_root
def left_rotate(self):
new_root = self.right
new_root.parent = self.parent
self.right = new_root.left
if self.right:
self.right.parent = self
new_root.left = self
self.parent = new_root
if new_root.parent:
if new_root.parent.left is self:
new_root.parent.left = new_root
else:
new_root.parent.right = new_root
self.update_balance()
new_root.update_balance()
return new_root
def right_left_rotate(self):
self.right = self.right.right_rotate()
return self.left_rotate()
def left_right_rotate(self):
self.left = self.left.left_rotate()
return self.right_rotate()