diff --git a/pydatastructs/trees/binary_trees.py b/pydatastructs/trees/binary_trees.py index a249029c3..d58b1b39e 100644 --- a/pydatastructs/trees/binary_trees.py +++ b/pydatastructs/trees/binary_trees.py @@ -552,10 +552,29 @@ def lowest_common_ancestor(self, j, k, algorithm=1): """ return getattr(self, "_lca_"+str(algorithm))(j, k) -class SelfBalancingBinaryTree(BinarySearchTree): +class AVLTree(BinarySearchTree): """ - Represents Base class for all rotation based balancing trees like AVL tree, Red Black tree, Splay Tree. + Represents AVL trees. + + References + ========== + + .. [1] https://courses.cs.washington.edu/courses/cse373/06sp/handouts/lecture12.pdf + .. [2] https://en.wikipedia.org/wiki/AVL_tree + .. [3] http://faculty.cs.niu.edu/~freedman/340/340notes/340avl2.htm + + See Also + ======== + + pydatastructs.trees.binary_trees.BinaryTree """ + left_height = lambda self, node: self.tree[node.left].height \ + if node.left is not None else -1 + right_height = lambda self, node: self.tree[node.right].height \ + if node.right is not None else -1 + balance_factor = lambda self, node: self.right_height(node) - \ + self.left_height(node) + def _right_rotate(self, j, k): y = self.tree[k].right if y is not None: @@ -566,6 +585,14 @@ def _right_rotate(self, j, k): self.tree[self.tree[k].parent].left = k self.tree[j].parent = k self.tree[k].right = j + self.tree[j].height = max(self.left_height(self.tree[j]), + self.right_height(self.tree[j])) + 1 + kp = self.tree[k].parent + if kp is None: + self.root_idx = k + if self.is_order_statistic: + self.tree[j].size = (self.left_size(self.tree[j]) + + self.right_size(self.tree[j]) + 1) def _left_right_rotate(self, j, k): i = self.tree[k].right @@ -578,6 +605,10 @@ def _left_right_rotate(self, j, k): self.tree[i].left, self.tree[i].right, self.tree[i].parent = \ k, j, self.tree[j].parent self.tree[k].parent, self.tree[j].parent = i, i + self.tree[j].height = max(self.left_height(self.tree[j]), + self.right_height(self.tree[j])) + 1 + self.tree[k].height = max(self.left_height(self.tree[k]), + self.right_height(self.tree[k])) + 1 ip = self.tree[i].parent if ip is not None: if self.tree[ip].left == j: @@ -586,6 +617,11 @@ def _left_right_rotate(self, j, k): self.tree[ip].right = i else: self.root_idx = i + if self.is_order_statistic: + self.tree[j].size = (self.left_size(self.tree[j]) + + self.right_size(self.tree[j]) + 1) + self.tree[k].size = (self.left_size(self.tree[k]) + + self.right_size(self.tree[k]) + 1) def _right_left_rotate(self, j, k): i = self.tree[k].left @@ -598,6 +634,10 @@ def _right_left_rotate(self, j, k): self.tree[i].right, self.tree[i].left, self.tree[i].parent = \ k, j, self.tree[j].parent self.tree[k].parent, self.tree[j].parent = i, i + self.tree[j].height = max(self.left_height(self.tree[j]), + self.right_height(self.tree[j])) + 1 + self.tree[k].height = max(self.left_height(self.tree[k]), + self.right_height(self.tree[k])) + 1 ip = self.tree[i].parent if ip is not None: if self.tree[ip].left == j: @@ -606,6 +646,11 @@ def _right_left_rotate(self, j, k): self.tree[ip].right = i else: self.root_idx = i + if self.is_order_statistic: + self.tree[j].size = (self.left_size(self.tree[j]) + + self.right_size(self.tree[j]) + 1) + self.tree[k].size = (self.left_size(self.tree[k]) + + self.right_size(self.tree[k]) + 1) def _left_rotate(self, j, k): y = self.tree[k].left @@ -617,67 +662,6 @@ def _left_rotate(self, j, k): self.tree[self.tree[k].parent].right = k self.tree[j].parent = k self.tree[k].left = j - -class AVLTree(SelfBalancingBinaryTree): - """ - Represents AVL trees. - - References - ========== - - .. [1] https://courses.cs.washington.edu/courses/cse373/06sp/handouts/lecture12.pdf - .. [2] https://en.wikipedia.org/wiki/AVL_tree - .. [3] http://faculty.cs.niu.edu/~freedman/340/340notes/340avl2.htm - - See Also - ======== - - pydatastructs.trees.binary_trees.BinaryTree - """ - left_height = lambda self, node: self.tree[node.left].height \ - if node.left is not None else -1 - right_height = lambda self, node: self.tree[node.right].height \ - if node.right is not None else -1 - balance_factor = lambda self, node: self.right_height(node) - \ - self.left_height(node) - - def _right_rotate(self, j, k): - super(AVLTree, self)._right_rotate(j, k) - self.tree[j].height = max(self.left_height(self.tree[j]), - self.right_height(self.tree[j])) + 1 - kp = self.tree[k].parent - if kp is None: - self.root_idx = k - if self.is_order_statistic: - self.tree[j].size = (self.left_size(self.tree[j]) + - self.right_size(self.tree[j]) + 1) - - def _left_right_rotate(self, j, k): - super(AVLTree, self)._left_right_rotate(j, k) - self.tree[j].height = max(self.left_height(self.tree[j]), - self.right_height(self.tree[j])) + 1 - self.tree[k].height = max(self.left_height(self.tree[k]), - self.right_height(self.tree[k])) + 1 - if self.is_order_statistic: - self.tree[j].size = (self.left_size(self.tree[j]) + - self.right_size(self.tree[j]) + 1) - self.tree[k].size = (self.left_size(self.tree[k]) + - self.right_size(self.tree[k]) + 1) - - def _right_left_rotate(self, j, k): - super(AVLTree, self)._right_left_rotate(j, k) - self.tree[j].height = max(self.left_height(self.tree[j]), - self.right_height(self.tree[j])) + 1 - self.tree[k].height = max(self.left_height(self.tree[k]), - self.right_height(self.tree[k])) + 1 - if self.is_order_statistic: - self.tree[j].size = (self.left_size(self.tree[j]) + - self.right_size(self.tree[j]) + 1) - self.tree[k].size = (self.left_size(self.tree[k]) + - self.right_size(self.tree[k]) + 1) - - def _left_rotate(self, j, k): - super(AVLTree, self)._left_rotate(j, k) self.tree[j].height = max(self.left_height(self.tree[j]), self.right_height(self.tree[j])) + 1 self.tree[k].height = max(self.left_height(self.tree[k]),