|
4 | 4 | OneDimensionalArray, DynamicOneDimensionalArray) |
5 | 5 | from pydatastructs.linear_data_structures.arrays import ArrayForTrees |
6 | 6 | from collections import deque as Queue |
| 7 | +from copy import deepcopy |
7 | 8 |
|
8 | 9 | __all__ = [ |
9 | 10 | 'AVLTree', |
@@ -279,6 +280,7 @@ def delete(self, key, **kwargs): |
279 | 280 |
|
280 | 281 | elif self.tree[walk].left is not None and \ |
281 | 282 | self.tree[walk].right is not None: |
| 283 | + print(walk) |
282 | 284 | twalk = self.tree[walk].right |
283 | 285 | par = walk |
284 | 286 | flag = False |
@@ -755,6 +757,139 @@ def delete(self, key, **kwargs): |
755 | 757 | self._balance_deletion(a, key) |
756 | 758 | return True |
757 | 759 |
|
| 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 | + |
758 | 893 | class BinaryTreeTraversal(object): |
759 | 894 | """ |
760 | 895 | Represents the traversals possible in |
@@ -1060,120 +1195,3 @@ def get_sum(self, left_index, right_index): |
1060 | 1195 | self.get_prefix_sum(left_index - 1) |
1061 | 1196 | else: |
1062 | 1197 | 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 |
|
0 commit comments