|
1 | | -from pydatastructs.utils import TreeNode, CartesianTreeNode |
| 1 | +from pydatastructs.utils import TreeNode, CartesianTreeNode, RedBlackTreeNode |
2 | 2 | from pydatastructs.miscellaneous_data_structures import Stack |
3 | 3 | from pydatastructs.linear_data_structures import ( |
4 | 4 | OneDimensionalArray, DynamicOneDimensionalArray) |
|
15 | 15 | 'BinaryIndexedTree', |
16 | 16 | 'CartesianTree', |
17 | 17 | 'Treap', |
18 | | - 'SplayTree' |
| 18 | + 'SplayTree', |
| 19 | + 'RedBlackTree' |
19 | 20 | ] |
20 | 21 |
|
21 | 22 | class BinaryTree(object): |
@@ -1057,6 +1058,349 @@ def split(self, x): |
1057 | 1058 | self.tree[self.root_idx].right = None |
1058 | 1059 | return other |
1059 | 1060 |
|
| 1061 | +class RedBlackTree(SelfBalancingBinaryTree): |
| 1062 | + """ |
| 1063 | + Represents Red Black trees. |
| 1064 | +
|
| 1065 | + Examples |
| 1066 | + ======== |
| 1067 | +
|
| 1068 | + >>> from pydatastructs.trees import RedBlackTree as RB |
| 1069 | + >>> b = RB() |
| 1070 | + >>> b.insert(1, 1) |
| 1071 | + >>> b.insert(2, 2) |
| 1072 | + >>> child = b.tree[b.root_idx].right |
| 1073 | + >>> b.tree[child].data |
| 1074 | + 2 |
| 1075 | + >>> b.search(1) |
| 1076 | + 0 |
| 1077 | +
|
| 1078 | + References |
| 1079 | + ========== |
| 1080 | +
|
| 1081 | + .. [1] https://en.wikipedia.org/wiki/Red%E2%80%93black_tree |
| 1082 | +
|
| 1083 | + See Also |
| 1084 | + ======== |
| 1085 | +
|
| 1086 | + pydatastructs.trees.binary_tree.SelfBalancingBinaryTree |
| 1087 | + """ |
| 1088 | + |
| 1089 | + @classmethod |
| 1090 | + def methods(cls): |
| 1091 | + return ['insert', 'delete'] |
| 1092 | + |
| 1093 | + def _get_parent(self, node_idx): |
| 1094 | + return self.tree[node_idx].parent |
| 1095 | + |
| 1096 | + def _get_grand_parent(self, node_idx): |
| 1097 | + parent_idx=self._get_parent(node_idx) |
| 1098 | + return self.tree[parent_idx].parent |
| 1099 | + |
| 1100 | + def _get_sibling(self, node_idx): |
| 1101 | + parent_idx=self._get_parent(node_idx) |
| 1102 | + if parent_idx is None: |
| 1103 | + return None |
| 1104 | + node = self.tree[parent_idx] |
| 1105 | + if node_idx==node.left: |
| 1106 | + sibling_idx=node.right |
| 1107 | + return sibling_idx |
| 1108 | + else: |
| 1109 | + sibling_idx=node.left |
| 1110 | + return sibling_idx |
| 1111 | + |
| 1112 | + def _get_uncle(self, node_idx): |
| 1113 | + parent_idx=self._get_parent(node_idx) |
| 1114 | + return self._get_sibling(parent_idx) |
| 1115 | + |
| 1116 | + def _is_onleft(self, node_idx): |
| 1117 | + parent = self._get_parent(node_idx) |
| 1118 | + if self.tree[parent].left == node_idx: |
| 1119 | + return True |
| 1120 | + return False |
| 1121 | + |
| 1122 | + def _is_onright(self, node_idx): |
| 1123 | + if self._is_onleft(node_idx) is False: |
| 1124 | + return True |
| 1125 | + return False |
| 1126 | + |
| 1127 | + def __fix_insert(self, node_idx): |
| 1128 | + while self._get_parent(node_idx) is not None and \ |
| 1129 | + self.tree[self._get_parent(node_idx)].color == 1 and self.tree[node_idx].color==1: |
| 1130 | + parent_idx=self._get_parent(node_idx) |
| 1131 | + grand_parent_idx=self._get_grand_parent(node_idx) |
| 1132 | + uncle_idx = self._get_uncle(node_idx) |
| 1133 | + if uncle_idx is not None and self.tree[uncle_idx].color == 1: |
| 1134 | + self.tree[uncle_idx].color = 0 |
| 1135 | + self.tree[parent_idx].color = 0 |
| 1136 | + self.tree[grand_parent_idx].color = 1 |
| 1137 | + node_idx= grand_parent_idx |
| 1138 | + else: |
| 1139 | + self.tree[self.root_idx].is_root=False |
| 1140 | + if self._is_onright(parent_idx): |
| 1141 | + if self._is_onleft(node_idx): |
| 1142 | + self._right_rotate(parent_idx, node_idx) |
| 1143 | + node_idx=parent_idx |
| 1144 | + parent_idx=self._get_parent(node_idx) |
| 1145 | + node_idx=parent_idx |
| 1146 | + parent_idx=self._get_parent(node_idx) |
| 1147 | + self._left_rotate(parent_idx, node_idx) |
| 1148 | + elif self._is_onleft(parent_idx): |
| 1149 | + if self._is_onright(node_idx): |
| 1150 | + self._left_rotate(parent_idx, node_idx) |
| 1151 | + node_idx=parent_idx |
| 1152 | + parent_idx=self._get_parent(node_idx) |
| 1153 | + node_idx=parent_idx |
| 1154 | + parent_idx=self._get_parent(node_idx) |
| 1155 | + self._right_rotate(parent_idx, node_idx) |
| 1156 | + self.tree[node_idx].color = 0 |
| 1157 | + self.tree[parent_idx].color = 1 |
| 1158 | + self.tree[self.root_idx].is_root=True |
| 1159 | + if self.tree[node_idx].is_root: |
| 1160 | + break |
| 1161 | + self.tree[self.root_idx].color=0 |
| 1162 | + |
| 1163 | + def insert(self, key, data=None): |
| 1164 | + super(RedBlackTree, self).insert(key, data) |
| 1165 | + node_idx = super(RedBlackTree, self).search(key) |
| 1166 | + node = self.tree[node_idx] |
| 1167 | + new_node = RedBlackTreeNode(key, data) |
| 1168 | + new_node.parent = node.parent |
| 1169 | + new_node.left = node.left |
| 1170 | + new_node.right = node.right |
| 1171 | + self.tree[node_idx] = new_node |
| 1172 | + if node.is_root: |
| 1173 | + self.tree[node_idx].is_root = True |
| 1174 | + self.tree[node_idx].color=0 |
| 1175 | + elif self.tree[self.tree[node_idx].parent].color==1: |
| 1176 | + self.__fix_insert(node_idx) |
| 1177 | + |
| 1178 | + def _find_predecessor(self, node_idx): |
| 1179 | + while self.tree[node_idx].right is not None: |
| 1180 | + node_idx = self.tree[node_idx].right |
| 1181 | + return node_idx |
| 1182 | + |
| 1183 | + def _transplant_values(self, node_idx1, node_idx2): |
| 1184 | + parent = self.tree[node_idx1].parent |
| 1185 | + if self.tree[node_idx1].is_root and self._has_one_child(node_idx1): |
| 1186 | + self.tree[self.root_idx].key = self.tree[node_idx2].key |
| 1187 | + self.tree[self.root_idx].data = self.tree[node_idx2].data |
| 1188 | + self.tree[self.root_idx].left = self.tree[node_idx2].left |
| 1189 | + self.tree[self.root_idx].right = self.tree[node_idx2].right |
| 1190 | + self.tree[node_idx1].parent = None |
| 1191 | + return self.tree[self.root_idx].key |
| 1192 | + else: |
| 1193 | + self.tree[node_idx1].key = self.tree[node_idx2].key |
| 1194 | + self.tree[node_idx1].data = self.tree[node_idx2].data |
| 1195 | + |
| 1196 | + def _has_one_child(self, node_idx): |
| 1197 | + if self._is_leaf(node_idx) is False and self._has_two_child(node_idx) is False: |
| 1198 | + return True |
| 1199 | + return False |
| 1200 | + |
| 1201 | + def _is_leaf(self, node_idx): |
| 1202 | + if self.tree[node_idx].left is None and self.tree[node_idx].right is None: |
| 1203 | + return True |
| 1204 | + return False |
| 1205 | + |
| 1206 | + def _has_two_child(self, node_idx): |
| 1207 | + if self.tree[node_idx].left is not None and self.tree[node_idx].right is not None: |
| 1208 | + return True |
| 1209 | + return False |
| 1210 | + |
| 1211 | + def __has_red_child(self, node_idx): |
| 1212 | + left_idx = self.tree[node_idx].left |
| 1213 | + right_idx = self.tree[node_idx].right |
| 1214 | + if (left_idx is not None and self.tree[left_idx].color == 1) or \ |
| 1215 | + (right_idx is not None and self.tree[right_idx].color == 1): |
| 1216 | + return True |
| 1217 | + return False |
| 1218 | + |
| 1219 | + def _replace_node(self, node_idx): |
| 1220 | + if self._is_leaf(node_idx): |
| 1221 | + return None |
| 1222 | + elif self._has_one_child(node_idx): |
| 1223 | + if self.tree[node_idx].left is not None: |
| 1224 | + child = self.tree[node_idx].left |
| 1225 | + else: |
| 1226 | + child = self.tree[node_idx].right |
| 1227 | + return child |
| 1228 | + else: |
| 1229 | + return self._find_predecessor(self.tree[node_idx].left) |
| 1230 | + |
| 1231 | + def __walk1_walk_isblack(self, color, node_idx1): |
| 1232 | + if (node_idx1 is None or self.tree[node_idx1].color == 0) and (color == 0): |
| 1233 | + return True |
| 1234 | + return False |
| 1235 | + |
| 1236 | + def __left_left_siblingcase(self, node_idx): |
| 1237 | + left_idx = self.tree[node_idx].left |
| 1238 | + parent = self._get_parent(node_idx) |
| 1239 | + parent_color = self.tree[parent].color |
| 1240 | + self.tree[left_idx].color = self.tree[node_idx].color |
| 1241 | + self.tree[node_idx].color = parent_color |
| 1242 | + self._right_rotate(parent, node_idx) |
| 1243 | + |
| 1244 | + def __right_left_siblingcase(self, node_idx): |
| 1245 | + left_idx = self.tree[node_idx].left |
| 1246 | + parent = self._get_parent(node_idx) |
| 1247 | + parent_color = self.tree[parent].color |
| 1248 | + self.tree[left_idx].color = parent_color |
| 1249 | + self._right_rotate(node_idx, left_idx) |
| 1250 | + child = self._get_parent(node_idx) |
| 1251 | + self._left_rotate(parent, child) |
| 1252 | + |
| 1253 | + def __left_right_siblingcase(self, node_idx): |
| 1254 | + right_idx = self.tree[node_idx].right |
| 1255 | + parent = self._get_parent(node_idx) |
| 1256 | + parent_color = self.tree[parent].color |
| 1257 | + self.tree[right_idx].color = parent_color |
| 1258 | + self._left_rotate(node_idx, right_idx) |
| 1259 | + child = self._get_parent(node_idx) |
| 1260 | + self._right_rotate(parent, child) |
| 1261 | + |
| 1262 | + def __right_right_siblingcase(self, node_idx): |
| 1263 | + right_idx = self.tree[node_idx].right |
| 1264 | + parent = self._get_parent(node_idx) |
| 1265 | + parent_color = self.tree[parent].color |
| 1266 | + self.tree[right_idx].color = self.tree[node_idx].color |
| 1267 | + self.tree[node_idx].color = parent_color |
| 1268 | + self._left_rotate(parent, node_idx) |
| 1269 | + |
| 1270 | + def __fix_deletion(self, node_idx): |
| 1271 | + node = self.tree[node_idx] |
| 1272 | + color = node.color |
| 1273 | + while node_idx!= self.root_idx and color == 0: |
| 1274 | + sibling_idx = self._get_sibling(node_idx) |
| 1275 | + parent_idx = self._get_parent(node_idx) |
| 1276 | + if sibling_idx is None: |
| 1277 | + node_idx = parent_idx |
| 1278 | + continue |
| 1279 | + else: |
| 1280 | + if self.tree[sibling_idx].color == 1: |
| 1281 | + self.tree[self.root_idx].is_root = False |
| 1282 | + self.tree[parent_idx].color = 1 |
| 1283 | + self.tree[sibling_idx].color = 0 |
| 1284 | + if self._is_onleft(sibling_idx): |
| 1285 | + self._right_rotate(parent_idx, sibling_idx) |
| 1286 | + else: |
| 1287 | + self._left_rotate(parent_idx, sibling_idx) |
| 1288 | + self.tree[self.root_idx].is_root = True |
| 1289 | + continue |
| 1290 | + else: |
| 1291 | + if self.__has_red_child(sibling_idx): |
| 1292 | + self.tree[self.root_idx].is_root = False |
| 1293 | + left_idx = self.tree[sibling_idx].left |
| 1294 | + if self.tree[sibling_idx].left is not None and \ |
| 1295 | + self.tree[left_idx].color == 1: |
| 1296 | + if self._is_onleft(sibling_idx): |
| 1297 | + self.__left_left_siblingcase(sibling_idx) |
| 1298 | + else: |
| 1299 | + self.__right_left_siblingcase(sibling_idx) |
| 1300 | + else: |
| 1301 | + if self._is_onleft(sibling_idx): |
| 1302 | + self.__left_right_siblingcase(sibling_idx) |
| 1303 | + else: |
| 1304 | + self.__right_right_siblingcase(sibling_idx) |
| 1305 | + self.tree[self.root_idx].is_root = True |
| 1306 | + self.tree[parent_idx].color = 0 |
| 1307 | + else: |
| 1308 | + self.tree[sibling_idx].color = 1 |
| 1309 | + if self.tree[parent_idx].color == 0: |
| 1310 | + node_idx = parent_idx |
| 1311 | + continue |
| 1312 | + else: |
| 1313 | + self.tree[parent_idx].color = 0 |
| 1314 | + color = 1 |
| 1315 | + |
| 1316 | + def _remove_node(self, node_idx): |
| 1317 | + parent = self._get_parent(node_idx) |
| 1318 | + a = parent |
| 1319 | + if self._is_leaf(node_idx): |
| 1320 | + par_key, root_key = (self.tree[parent].key, self.tree[self.root_idx].key) |
| 1321 | + new_indices = self.tree.delete(node_idx) |
| 1322 | + if new_indices is not None: |
| 1323 | + a = new_indices[par_key] |
| 1324 | + self.root_idx = new_indices[root_key] |
| 1325 | + elif self._has_one_child(node_idx): |
| 1326 | + child = self._replace_node(node_idx) |
| 1327 | + parent = self._get_parent(node_idx) |
| 1328 | + par_key, root_key = (self.tree[parent].key, self.tree[self.root_idx].key) |
| 1329 | + new_indices = self.tree.delete(node_idx) |
| 1330 | + self._update_size(a) |
| 1331 | + |
| 1332 | + def _delete_root(self, node_idx, node_idx1): |
| 1333 | + if self._is_leaf(node_idx): |
| 1334 | + self.tree[self.root_idx].data = None |
| 1335 | + self.tree[self.root_idx].key = None |
| 1336 | + elif self._has_one_child(node_idx): |
| 1337 | + root_key = self._transplant_values(node_idx, node_idx1) |
| 1338 | + new_indices = self.tree.delete(node_idx1) |
| 1339 | + if new_indices is not None: |
| 1340 | + self.root_idx = new_indices[root_key] |
| 1341 | + return |
| 1342 | + |
| 1343 | + def __leaf_case(self, node_idx, node_idx1): |
| 1344 | + walk = node_idx |
| 1345 | + walk1 = node_idx1 |
| 1346 | + parent = self._get_parent(node_idx) |
| 1347 | + color = self.tree[walk].color |
| 1348 | + if parent is None: |
| 1349 | + self._delete_root(walk, walk1) |
| 1350 | + else: |
| 1351 | + if self.__walk1_walk_isblack(color, walk1): |
| 1352 | + self.__fix_deletion(walk) |
| 1353 | + else: |
| 1354 | + sibling_idx = self._get_sibling(walk) |
| 1355 | + if sibling_idx is not None: |
| 1356 | + self.tree[sibling_idx].color = 1 |
| 1357 | + if self._is_onleft(walk): |
| 1358 | + self.tree[parent].left = None |
| 1359 | + else: |
| 1360 | + self.tree[parent].right = None |
| 1361 | + self._remove_node(walk) |
| 1362 | + |
| 1363 | + def __one_child_case(self, node_idx, node_idx1): |
| 1364 | + walk = node_idx |
| 1365 | + walk1 = node_idx1 |
| 1366 | + walk_original_color = self.tree[walk].color |
| 1367 | + parent = self._get_parent(node_idx) |
| 1368 | + if parent is None: |
| 1369 | + self._delete_root(walk, walk1) |
| 1370 | + else: |
| 1371 | + if self._is_onleft(walk): |
| 1372 | + self.tree[parent].left = walk1 |
| 1373 | + else: |
| 1374 | + self.tree[parent].right = walk1 |
| 1375 | + self.tree[walk1].parent = parent |
| 1376 | + a = self._remove_node(walk) |
| 1377 | + if self.__walk1_walk_isblack(walk_original_color, walk1): |
| 1378 | + self.__fix_deletion(walk1) |
| 1379 | + else: |
| 1380 | + self.tree[walk1].color = 0 |
| 1381 | + |
| 1382 | + def __two_child_case(self, node_idx): |
| 1383 | + walk = node_idx |
| 1384 | + successor = self._replace_node(walk) |
| 1385 | + self._transplant_values(walk, successor) |
| 1386 | + walk = successor |
| 1387 | + walk1 = self._replace_node(walk) |
| 1388 | + return walk, walk1 |
| 1389 | + |
| 1390 | + def delete(self, key, **kwargs): |
| 1391 | + walk = super(RedBlackTree, self).search(key) |
| 1392 | + if walk is not None: |
| 1393 | + walk1 = self._replace_node(walk) |
| 1394 | + if self._has_two_child(walk): |
| 1395 | + walk, walk1 = self.__two_child_case(walk) |
| 1396 | + if self._is_leaf(walk): |
| 1397 | + self.__leaf_case(walk, walk1) |
| 1398 | + elif self._has_one_child(walk): |
| 1399 | + self.__one_child_case(walk, walk1) |
| 1400 | + return True |
| 1401 | + else: |
| 1402 | + return None |
| 1403 | + |
1060 | 1404 | class BinaryTreeTraversal(object): |
1061 | 1405 | """ |
1062 | 1406 | Represents the traversals possible in |
|
0 commit comments