diff --git a/data_structures/AVL/AVL.py b/data_structures/AVL/AVL.py index 0e3008dc1..9717f1b6e 100644 --- a/data_structures/AVL/AVL.py +++ b/data_structures/AVL/AVL.py @@ -7,40 +7,42 @@ class Node: def __init__(self, label): self.label = label - self.left = None - self.rigt = None - self.parent = None + self._parent = None + self._left = None + self._right = None self.height = 0 - def getLabel(self): - return self.label + @property + def right(self): + return self._right - def setLabel(self, label): - self.label = label + @right.setter + def right(self, node): + if node is not None: + node._parent = self + self._right = node - def getLeft(self): - return self.left + @property + def left(self): + return self._left - def setLeft(self, left): - self.left = left + @left.setter + def left(self, node): + if node is not None: + node._parent = self + self._left = node - def getRight(self): - return self.rigt + @property + def parent(self): + return self._parent - def setRight(self, right): - self.rigt = right - - def getParent(self): - return self.parent - - def setParent(self, parent): - self.parent = parent - - def setHeight(self, height): - self.height = height - - def getHeight(self, height): - return self.height + @parent.setter + def parent(self, node): + if node is not None: + self._parent = node + self.height = self.parent.height + 1 + else: + self.height = 0 class AVL: @@ -51,8 +53,10 @@ class AVL: def insert(self, value): node = Node(value) + if self.root is None: self.root = node + self.root.height = 0 self.size = 1 else: # Same as Binary Tree @@ -64,63 +68,77 @@ class AVL: dad_node = curr_node - if node.getLabel() < curr_node.getLabel(): - curr_node = curr_node.getLeft() + if node.label < curr_node.label: + curr_node = curr_node.left else: - curr_node = curr_node.getRight() + curr_node = curr_node.right else: - if node.getLabel() < dad_node.getLabel(): - dad_node.setLeft(node) - dad_node.setHeight(dad_node.getHeight() + 1) - - if (dad_node.getRight().getHeight() - - dad_node.getLeft.getHeight() > 1): - self.rebalance(dad_node) - + node.height = dad_node.height + dad_node.height += 1 + if node.label < dad_node.label: + dad_node.left = node else: - dad_node.setRight(node) - dad_node.setHeight(dad_node.getHeight() + 1) - - if (dad_node.getRight().getHeight() - - dad_node.getLeft.getHeight() > 1): - self.rebalance(dad_node) + dad_node.right = node + self.rebalance(node) + self.size += 1 break def rebalance(self, node): - if (node.getRight().getHeight() - - node.getLeft.getHeight() > 1): - if (node.getRight().getHeight() > - node.getLeft.getHeight()): - pass - else: - pass - pass - elif (node.getRight().getHeight() - - node.getLeft.getHeight() > 2): - if (node.getRight().getHeight() > - node.getLeft.getHeight()): - pass - else: - pass - pass - pass + n = node + + while n is not None: + height_right = n.height + height_left = n.height + + if n.right is not None: + height_right = n.right.height + + if n.left is not None: + height_left = n.left.height + + if abs(height_left - height_right) > 1: + if height_left > height_right: + left_child = n.left + if left_child is not None: + h_right = (right_child.right.height + if (right_child.right is not None) else 0) + h_left = (right_child.left.height + if (right_child.left is not None) else 0) + if (h_left > h_right): + self.rotate_left(n) + break + else: + self.double_rotate_right(n) + break + else: + right_child = n.right + if right_child is not None: + h_right = (right_child.right.height + if (right_child.right is not None) else 0) + h_left = (right_child.left.height + if (right_child.left is not None) else 0) + if (h_left > h_right): + self.double_rotate_left(n) + break + else: + self.rotate_right(n) + break + n = n.parent def rotate_left(self, node): - # TODO: is this pythonic enought? - aux = node.getLabel() - node = aux.getRight() - node.setHeight(node.getHeight() - 1) - node.setLeft(Node(aux)) - node.getLeft().setHeight(node.getHeight() + 1) - node.getRight().setHeight(node.getRight().getHeight() - 1) + aux = node.parent.label + node.parent.label = node.label + node.parent.right = Node(aux) + node.parent.right.height = node.parent.height + 1 + node.parent.left = node.right + def rotate_right(self, node): - aux = node.getLabel() - node = aux.getLeft() - node.setHeight(node.getHeight() - 1) - node.setRight(Node(aux)) - node.getLeft().setHeight(node.getHeight() + 1) - node.getLeft().setHeight(node.getLeft().getHeight() - 1) + aux = node.parent.label + node.parent.label = node.label + node.parent.left = Node(aux) + node.parent.left.height = node.parent.height + 1 + node.parent.right = node.right def double_rotate_left(self, node): self.rotate_right(node.getRight().getRight()) @@ -129,3 +147,34 @@ class AVL: def double_rotate_right(self, node): self.rotate_left(node.getLeft().getLeft()) self.rotate_right(node) + + def empty(self): + if self.root is None: + return True + return False + + def preShow(self, curr_node): + if curr_node is not None: + self.preShow(curr_node.left) + print(curr_node.label, end=" ") + self.preShow(curr_node.right) + + def preorder(self, curr_node): + if curr_node is not None: + self.preShow(curr_node.left) + self.preShow(curr_node.right) + print(curr_node.label, end=" ") + + def getRoot(self): + return self.root + +t = AVL() +t.insert(1) +t.insert(2) +t.insert(3) +# t.preShow(t.root) +# print("\n") +# t.insert(4) +# t.insert(5) +# t.preShow(t.root) +# t.preorden(t.root) diff --git a/data_structures/Binary Tree/binary_seach_tree.py b/data_structures/Binary Tree/binary_seach_tree.py index 0b1726534..9e468f775 100644 --- a/data_structures/Binary Tree/binary_seach_tree.py +++ b/data_structures/Binary Tree/binary_seach_tree.py @@ -68,7 +68,7 @@ class BinarySearchTree: return False def preShow(self, curr_node): - if curr_node is None: + if curr_node is not None: print(curr_node.getLabel(), end=" ") self.preShow(curr_node.getLeft())