You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

avl_tree.py 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. from SoSe24.algodat.foundation import AlgoDatArray, AlgoDatValue, read_int_sequence
  2. from SoSe24.lec04_trees.bin_tree import BinTree, BinTreeNode
  3. from time import perf_counter as pfc
  4. class AVLTreeNode(BinTreeNode):
  5. def __init__(self, value: AlgoDatValue):
  6. super().__init__(value)
  7. self.parent = None
  8. self.balance = 0
  9. def update_balance(self):
  10. left_height = self.left.height() if self.left else 0
  11. right_height = self.right.height() if self.right else 0
  12. self.balance = right_height - left_height
  13. def right_rotate(self) -> BinTreeNode:
  14. new_root = self.left
  15. new_root.parent = self.parent
  16. self.left = new_root.right
  17. if self.left:
  18. self.left.parent = self
  19. new_root.right = self
  20. self.parent = new_root
  21. if new_root.parent:
  22. if new_root.parent.left == self:
  23. new_root.parent.left = new_root
  24. else:
  25. new_root.parent.right = new_root
  26. self.update_balance()
  27. new_root.update_balance()
  28. return new_root
  29. def left_rotate(self) -> BinTreeNode:
  30. new_root = self.right
  31. new_root.parent = self.parent
  32. self.right = new_root.left
  33. if self.right:
  34. self.right.parent = self
  35. new_root.left = self
  36. self.parent = new_root
  37. if new_root.parent:
  38. if new_root.parent.left == self:
  39. new_root.parent.left = new_root
  40. else:
  41. new_root.parent.right = new_root
  42. self.update_balance()
  43. new_root.update_balance()
  44. return new_root
  45. def right_left_rotate(self) -> BinTreeNode:
  46. self.right = self.right.right_rotate()
  47. return self.left_rotate()
  48. def left_right_rotate(self) -> BinTreeNode:
  49. self.left = self.left.left_rotate()
  50. return self.right_rotate()
  51. class AVLTree(BinTree):
  52. def new_node(self, value: AlgoDatValue):
  53. return AVLTreeNode(value)
  54. def balance(self, node: AVLTreeNode):
  55. node.update_balance()
  56. if node.balance == -2:
  57. if node.left.balance <= 0:
  58. node = node.right_rotate()
  59. else:
  60. node = node.left_right_rotate()
  61. elif node.balance == 2:
  62. if node.right.balance >= 0:
  63. node = node.left_rotate()
  64. else:
  65. node = node.right_left_rotate()
  66. if node.parent:
  67. self.balance(node.parent)
  68. else:
  69. self.root = node
  70. def insert(self, value: AlgoDatValue):
  71. node, parent = super().insert(value)
  72. node.parent = parent
  73. if parent:
  74. self.balance(parent)
  75. return node, parent
  76. def delete(self, value: AlgoDatValue):
  77. node, parent = super().delete(value)
  78. if node:
  79. node.parent = parent
  80. if parent:
  81. self.balance(parent)
  82. if __name__ == "__main__":
  83. z = read_int_sequence("../../seq0.txt")
  84. print(z, len(z))
  85. start = pfc()
  86. tree = AVLTree()
  87. for i in z:
  88. tree.insert(i)
  89. tree.walk()
  90. tree.tree_walk()
  91. tree.levelwalk()
  92. tree.graph_walk()
  93. tree.delete(AlgoDatValue(46))
  94. tree.delete(AlgoDatValue(48))
  95. #tree.graph_walk()
  96. print(f"Dauer: {pfc() - start:.4f}s")
  97. AlgoDatValue.summary()