Skip to content

Commit aa3c553

Browse files
committed
ready for merge
1 parent 4216965 commit aa3c553

File tree

2 files changed

+150
-124
lines changed

2 files changed

+150
-124
lines changed

pydatastructs/trees/binary_trees.py

Lines changed: 135 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
OneDimensionalArray, DynamicOneDimensionalArray)
55
from pydatastructs.linear_data_structures.arrays import ArrayForTrees
66
from collections import deque as Queue
7+
from copy import deepcopy
78

89
__all__ = [
910
'AVLTree',
@@ -279,6 +280,7 @@ def delete(self, key, **kwargs):
279280

280281
elif self.tree[walk].left is not None and \
281282
self.tree[walk].right is not None:
283+
print(walk)
282284
twalk = self.tree[walk].right
283285
par = walk
284286
flag = False
@@ -755,6 +757,139 @@ def delete(self, key, **kwargs):
755757
self._balance_deletion(a, key)
756758
return True
757759

760+
class SplayTree(SelfBalancingBinaryTree):
761+
"""
762+
Represents Splay Trees.
763+
764+
References
765+
==========
766+
767+
.. [1] https://en.wikipedia.org/wiki/Splay_tree
768+
769+
"""
770+
def _zig(self, x, p):
771+
if self.tree[p].left == x:
772+
super(SplayTree, self)._right_rotate(p, x)
773+
else:
774+
super(SplayTree, self)._left_rotate(p, x)
775+
776+
def _zig_zig(self, x, p):
777+
super(SplayTree, self)._right_rotate(self.tree[p].parent, p)
778+
super(SplayTree, self)._right_rotate(p, x)
779+
780+
def _zig_zag(self, p):
781+
super(SplayTree, self)._left_right_rotate(self.tree[p].parent, p)
782+
783+
def _zag_zag(self, x, p):
784+
super(SplayTree, self)._left_rotate(self.tree[p].parent, p)
785+
super(SplayTree, self)._left_rotate(p, x)
786+
787+
def _zag_zig(self, p):
788+
super(SplayTree, self)._right_left_rotate(self.tree[p].parent, p)
789+
790+
def splay(self, x, p):
791+
while self.tree[x].parent is not None:
792+
if self.tree[p].parent is None:
793+
self._zig(x, p)
794+
elif self.tree[p].left == x and \
795+
self.tree[self.tree[p].parent].left == p:
796+
self._zig_zig(x, p)
797+
elif self.tree[p].right == x and \
798+
self.tree[self.tree[p].parent].right == p:
799+
self._zag_zag(x, p)
800+
elif self.tree[p].left == x and \
801+
self.tree[self.tree[p].parent].right == p:
802+
self._zag_zig(p)
803+
else:
804+
self._zig_zag(p)
805+
p = self.tree[x].parent
806+
807+
def insert(self, key, x):
808+
super(SelfBalancingBinaryTree, self).insert(key, x)
809+
e, p = super(SelfBalancingBinaryTree, self).search(key, parent=True)
810+
self.tree[self.size-1].parent = p
811+
self.splay(e, p)
812+
813+
def delete(self, x):
814+
e, p = super(SelfBalancingBinaryTree, self).search(x, parent=True)
815+
if e is None:
816+
return
817+
self.splay(e, p)
818+
status = super(SelfBalancingBinaryTree, self).delete(x)
819+
return status
820+
821+
def join(self, other):
822+
"""
823+
Joins two trees current and other such that all elements of
824+
the current splay tree are smaller than the elements of the other tree.
825+
826+
Parameters
827+
==========
828+
829+
other: SplayTree
830+
SplayTree which needs to be joined with the self tree.
831+
832+
"""
833+
maxm = self.root_idx
834+
while self.tree[maxm].right is not None:
835+
maxm = self.tree[maxm].right
836+
minm = other.root_idx
837+
while other.tree[minm].left is not None:
838+
minm = other.tree[minm].left
839+
if not self.comparator(self.tree[maxm].key,
840+
other.tree[minm].key):
841+
raise ValueError("Elements of %s aren't less "
842+
"than that of %s"%(self, other))
843+
self.splay(maxm, self.tree[maxm].parent)
844+
idx_update = self.tree._size
845+
for node in other.tree:
846+
if node is not None:
847+
node_copy = TreeNode(node.key, node.data)
848+
if node.left is not None:
849+
node_copy.left = node.left + idx_update
850+
if node.right is not None:
851+
node_copy.right = node.right + idx_update
852+
self.tree.append(node_copy)
853+
else:
854+
self.tree.append(node)
855+
self.tree[self.root_idx].right = \
856+
other.root_idx + idx_update
857+
858+
def split(self, x):
859+
"""
860+
Splits current splay tree into two trees such that one tree contains nodes
861+
with key less than or equal to x and the other tree containing
862+
nodes with key greater than x.
863+
864+
Parameters
865+
==========
866+
867+
x: key
868+
Key of the element on the basis of which split is performed.
869+
870+
Returns
871+
=======
872+
873+
other: SplayTree
874+
SplayTree containing elements with key greater than x.
875+
876+
"""
877+
e, p = super(SelfBalancingBinaryTree, self).search(x, parent=True)
878+
if e is None:
879+
return
880+
self.splay(e, p)
881+
other = SplayTree(None, None)
882+
if self.tree[self.root_idx].right is not None:
883+
traverse = BinaryTreeTraversal(self)
884+
elements = traverse.depth_first_search(order='pre_order', node=self.tree[self.root_idx].right)
885+
for i in range(len(elements)):
886+
super(SelfBalancingBinaryTree, other).insert(elements[i].key, elements[i].data)
887+
for j in range(len(elements) - 1, -1, -1):
888+
e, p = super(SelfBalancingBinaryTree, self).search(elements[j].key, parent=True)
889+
self.tree[e] = None
890+
self.tree[self.root_idx].right = None
891+
return other
892+
758893
class BinaryTreeTraversal(object):
759894
"""
760895
Represents the traversals possible in
@@ -1060,120 +1195,3 @@ def get_sum(self, left_index, right_index):
10601195
self.get_prefix_sum(left_index - 1)
10611196
else:
10621197
return self.get_prefix_sum(right_index)
1063-
1064-
class SplayTree(SelfBalancingBinaryTree):
1065-
"""
1066-
Represents Splay Trees.
1067-
1068-
References
1069-
==========
1070-
1071-
.. [1] https://en.wikipedia.org/wiki/Splay_tree
1072-
1073-
"""
1074-
def _zig(self, x, p):
1075-
if self.tree[p].left == x:
1076-
super(SplayTree, self)._right_rotate(p, x)
1077-
else:
1078-
super(SplayTree, self)._left_rotate(p, x)
1079-
1080-
def _zig_zig(self, x, p):
1081-
super(SplayTree, self)._right_rotate(self.tree[p].parent, p)
1082-
super(SplayTree, self)._right_rotate(p, x)
1083-
1084-
def _zig_zag(self, x, p):
1085-
super(SplayTree, self)._left_right_rotate(self.tree[p].parent, p)
1086-
1087-
def _zag_zag(self, x, p):
1088-
super(SplayTree, self)._left_rotate(self.tree[p].parent, p)
1089-
super(SplayTree, self)._left_rotate(p, x)
1090-
1091-
def _zag_zig(self, x, p):
1092-
super(SplayTree, self)._right_left_rotate(self.tree[p].parent, p)
1093-
1094-
def splay(self, x, p):
1095-
while self.tree[x].parent is not None:
1096-
if self.tree[p].parent is None:
1097-
self._zig(x, p)
1098-
elif self.tree[p].left == x and self.tree[self.tree[p].parent].left == p:
1099-
self._zig_zig(x, p)
1100-
elif self.tree[p].right == x and self.tree[self.tree[p].parent].right == p:
1101-
self._zag_zag(x, p)
1102-
elif self.tree[p].left == x and self.tree[self.tree[p].parent].right == p:
1103-
self._zag_zig(x, p)
1104-
else:
1105-
self._zig_zag(x, p)
1106-
p = self.tree[x].parent
1107-
1108-
def insert(self, key, x):
1109-
super(SelfBalancingBinaryTree, self).insert(key, x)
1110-
e, p = super(SelfBalancingBinaryTree, self).search(key, parent=True)
1111-
self.tree[self.size-1].parent = p;
1112-
self.splay(e, p)
1113-
1114-
def delete(self, x):
1115-
e, p = super(SelfBalancingBinaryTree, self).search(x, parent=True)
1116-
if e is None:
1117-
return
1118-
self.splay(e, p)
1119-
b = super(SelfBalancingBinaryTree, self).delete(x, balancing_info=True)
1120-
return True
1121-
1122-
def join(self, other):
1123-
"""
1124-
Joins two trees current and other such that all elements of
1125-
the current splay tree are smaller than the elements of the other tree.
1126-
1127-
Parameters
1128-
==========
1129-
1130-
other: SplayTree
1131-
SplayTree which needs to be joined with the self tree.
1132-
1133-
"""
1134-
maxm = self.root_idx
1135-
while self.tree[maxm].right is not None:
1136-
maxm = self.tree[maxm].right
1137-
self.splay(maxm, self.tree[maxm].parent)
1138-
traverse = BinaryTreeTraversal(other)
1139-
elements = traverse.depth_first_search(order='pre_order', node=other.root_idx)
1140-
for i in range(len(elements)):
1141-
super(SelfBalancingBinaryTree, self).insert(elements[i].key, elements[i].data)
1142-
for j in range(len(elements) - 1, -1, -1):
1143-
e, p = super(SelfBalancingBinaryTree, other).search(elements[j].key, parent=True)
1144-
other.tree[e] = None
1145-
1146-
def split(self, x):
1147-
"""
1148-
Splits current splay tree into two trees such that one tree contains nodes
1149-
with key less than or equal to x and the other tree containing
1150-
nodes with key greater than x.
1151-
1152-
Parameters
1153-
==========
1154-
1155-
x: key
1156-
Key of the element on the basis of which split is performed.
1157-
1158-
Returns
1159-
=======
1160-
1161-
other: SplayTree
1162-
SplayTree containing elements with key greater than x.
1163-
1164-
"""
1165-
e, p = super(SelfBalancingBinaryTree, self).search(x, parent=True)
1166-
if e is None:
1167-
return
1168-
self.splay(e, p)
1169-
other = SplayTree(None, None)
1170-
if self.tree[self.root_idx].right is not None:
1171-
traverse = BinaryTreeTraversal(self)
1172-
elements = traverse.depth_first_search(order='pre_order', node=self.tree[self.root_idx].right)
1173-
for i in range(len(elements)):
1174-
super(SelfBalancingBinaryTree, other).insert(elements[i].key, elements[i].data)
1175-
for j in range(len(elements) - 1, -1, -1):
1176-
e, p = super(SelfBalancingBinaryTree, self).search(elements[j].key, parent=True)
1177-
self.tree[e] = None
1178-
self.tree[self.root_idx].right = None
1179-
return other

pydatastructs/trees/tests/test_binary_trees.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -358,19 +358,27 @@ def test_SplayTree():
358358
t.insert(20, 20)
359359
t.insert(55, 55)
360360

361-
assert str(t) == ("[(None, 100, 100, None), (None, 50, 50, None), (0, 200, 200, None), (None, 40, 40, 1), (5, 30, 30, 3), (None, 20, 20, None), (4, 55, 55, 2)]")
361+
assert str(t) == ("[(None, 100, 100, None), (None, 50, 50, None), "
362+
"(0, 200, 200, None), (None, 40, 40, 1), (5, 30, 30, 3), "
363+
"(None, 20, 20, None), (4, 55, 55, 2)]")
362364
t.delete(40)
363-
assert str(t) == ("[(None, 100, 100, None), '', (0, 200, 200, None), (4, 50, 50, 6), (5, 30, 30, None), (None, 20, 20, None), (None, 55, 55, 2)]")
365+
assert str(t) == ("[(None, 100, 100, None), '', (0, 200, 200, None), "
366+
"(4, 50, 50, 6), (5, 30, 30, None), (None, 20, 20, None), "
367+
"(None, 55, 55, 2)]")
364368
t.delete(150)
365-
assert str(t) == ("[(None, 100, 100, None), '', (0, 200, 200, None), (4, 50, 50, 6), (5, 30, 30, None), (None, 20, 20, None), (None, 55, 55, 2)]")
369+
assert str(t) == ("[(None, 100, 100, None), '', (0, 200, 200, None), (4, 50, 50, 6), "
370+
"(5, 30, 30, None), (None, 20, 20, None), (None, 55, 55, 2)]")
371+
366372
t1 = SplayTree(1000, 1000)
367373
t1.insert(2000, 2000)
368-
369374
assert str(t1) == ("[(None, 1000, 1000, None), (0, 2000, 2000, None)]")
370375

371376
t.join(t1)
372-
assert str(t) == ("[(None, 100, 100, None), '', (6, 200, 200, 7), (4, 50, 50, None), (5, 30, 30, None), (None, 20, 20, None), (3, 55, 55, 0), (8, 2000, 2000, None), (None, 1000, 1000, None)]")
373-
s = t.split(200)
377+
assert str(t) == ("[(None, 100, 100, None), '', (6, 200, 200, 8), (4, 50, 50, None), "
378+
"(5, 30, 30, None), (None, 20, 20, None), (3, 55, 55, 0), (None, 1000, 1000, None), "
379+
"(7, 2000, 2000, None), '']")
374380

381+
s = t.split(200)
375382
assert str(s) == ("[(1, 2000, 2000, None), (None, 1000, 1000, None)]")
376-
assert str(t) == ("[(None, 100, 100, None), '', (6, 200, 200, None), (4, 50, 50, None), (5, 30, 30, None), (None, 20, 20, None), (3, 55, 55, 0), '', '']")
383+
assert str(t) == ("[(None, 100, 100, None), '', (6, 200, 200, None), (4, 50, 50, None), "
384+
"(5, 30, 30, None), (None, 20, 20, None), (3, 55, 55, 0), '', '', '']")

0 commit comments

Comments
 (0)