diff --git a/pydatastructs/trees/binary_trees.py b/pydatastructs/trees/binary_trees.py index 15ad4909f..d10fd4380 100644 --- a/pydatastructs/trees/binary_trees.py +++ b/pydatastructs/trees/binary_trees.py @@ -552,29 +552,10 @@ def lowest_common_ancestor(self, j, k, algorithm=1): """ return getattr(self, "_lca_"+str(algorithm))(j, k) -class AVLTree(BinarySearchTree): +class SelfBalancingBinaryTree(BinarySearchTree): """ - 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 + Represents Base class for all rotation based balancing trees like AVL tree, Red Black tree, Splay Tree. """ - 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: @@ -585,14 +566,6 @@ 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 @@ -605,10 +578,6 @@ 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: @@ -617,11 +586,6 @@ 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 @@ -634,10 +598,6 @@ 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: @@ -646,11 +606,6 @@ 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 @@ -662,6 +617,67 @@ 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]),