Skip to content

Commit

Permalink
[WIP] Added base class SelfBalancingTree for Red Black Tree (#176)
Browse files Browse the repository at this point in the history
  • Loading branch information
HarsheetKakar authored Mar 19, 2020
1 parent a20e4e5 commit f75c300
Showing 1 changed file with 63 additions and 47 deletions.
110 changes: 63 additions & 47 deletions pydatastructs/trees/binary_trees.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
Expand All @@ -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:
Expand All @@ -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
Expand All @@ -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:
Expand All @@ -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
Expand All @@ -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]),
Expand Down

0 comments on commit f75c300

Please sign in to comment.