1
1
#include < iostream>
2
2
#include " hw3.h"
3
- #include < cstdlib>
4
3
5
4
class Node {
6
5
public:
@@ -23,13 +22,16 @@ Node::Node(int key) {
23
22
class RBTree {
24
23
public:
25
24
Node *root;
25
+ // Necessary nodes for delete fix(So we have no memory leak)
26
+ Node *replacingNode;
27
+ Node *siblingNode;
26
28
void RotateLeft (Node *node);
27
29
void RotateRight (Node *node);
28
30
void Insert (Node *node);
29
31
void InsertFix (Node *node);
30
32
void Transplant (Node *oldNode, Node *newNode);
31
33
void Delete (Node *node);
32
- void DeleteFix (Node *node);
34
+ void DeleteFix (Node *node, bool rep );
33
35
void InOrderWalk (Node *node);
34
36
Node* TreeMinimum (Node *begin);
35
37
RBTree ();
@@ -219,18 +221,41 @@ void RBTree::Delete(Node *node) {
219
221
Node *temp = node;
220
222
Node *replace = nullptr ;
221
223
bool originalIsRed = temp->isRed ;
224
+ bool rep = false ;
225
+
222
226
if (node->left == nullptr ){
223
227
replace = node->right ;
228
+
229
+ if (!replace){
230
+ rep = true ;
231
+ // If there is no replacing node, we have to create an artificial one
232
+ replace = new Node (0 );
233
+ this ->replacingNode = replace;
234
+ replace->isRed = false ;
235
+ replace->parent = node;
236
+ replace->parent ->right = replace;
237
+ }
238
+
224
239
Transplant (node, node->right );
240
+
225
241
} else if (node->right == nullptr ){
226
- replace = node->left ;
242
+ replace = node->left ; // Since we check the left child first, there is no need to create an artificial node
227
243
Transplant (node, node->left );
228
244
} else {
229
245
temp = TreeMinimum (node->right );
230
246
originalIsRed = temp->isRed ;
231
247
replace = temp->right ;
248
+ if (!replace){
249
+ rep = true ;
250
+ // If there is no replacing node, we have to create an artificial one
251
+ replace = new Node (0 );
252
+ this ->replacingNode = replace;
253
+ replace->isRed = false ;
254
+ replace->parent = temp;
255
+ replace->parent ->right = replace;
256
+ }
232
257
if (temp->parent == node){
233
- if (replace) replace->parent = temp;
258
+ replace->parent = temp;
234
259
} else {
235
260
Transplant (temp, temp->right );
236
261
temp->right = node->right ;
@@ -243,21 +268,33 @@ void RBTree::Delete(Node *node) {
243
268
}
244
269
245
270
if (!(originalIsRed))
246
- DeleteFix (replace);
271
+ DeleteFix (replace, rep );
247
272
}
248
273
249
- void RBTree::DeleteFix (Node *node) {
250
- Node *sibling;
251
- while (node && (node != root && !node->isRed )){
252
- if (node->parent && (node == node->parent ->left )){
274
+ void RBTree::DeleteFix (Node *node, bool rep) {
275
+
276
+ Node *sibling = nullptr ;
277
+ bool siblingChange = false ;
278
+ bool replaceChange = rep;
279
+
280
+ while (node != root && !node->isRed ){
281
+ if (node == node->parent ->left ){
253
282
sibling = node->parent ->right ;
254
- if (sibling && sibling->isRed ){
283
+ if (!sibling){
284
+ siblingChange = true ;
285
+ sibling = new Node (0 );
286
+ this ->siblingNode = sibling;
287
+ sibling->parent = node->parent ;
288
+ sibling->isRed = false ;
289
+ node->parent ->right = sibling;
290
+ }
291
+ if (sibling->isRed ){
255
292
sibling->isRed = false ;
256
293
node->parent ->isRed = true ;
257
294
RotateLeft (node->parent );
258
295
sibling = node->parent ->right ;
259
296
}
260
- if ((!sibling->left || !sibling->left ->isRed ) && (!sibling->right || !sibling->right )){
297
+ if ((!sibling->left || !sibling->left ->isRed ) && (!sibling->right || !sibling->right -> isRed )){
261
298
sibling->isRed = true ;
262
299
node = node->parent ;
263
300
} else {
@@ -275,41 +312,73 @@ void RBTree::DeleteFix(Node *node) {
275
312
}
276
313
} else {
277
314
sibling = node->parent ->left ;
278
- if (sibling && sibling->isRed ){
315
+ if (!sibling){
316
+ siblingChange = true ;
317
+ sibling = new Node (0 );
318
+ this ->siblingNode = sibling;
319
+ sibling->parent = node->parent ;
320
+ sibling->isRed = false ;
321
+ node->parent ->left = sibling;
322
+ }
323
+
324
+ if (sibling->isRed ){
279
325
sibling->isRed = false ;
280
326
node->parent ->isRed = true ;
281
- RotateLeft (node->parent );
327
+ RotateRight (node->parent );
282
328
sibling = node->parent ->left ;
283
329
}
284
- if ((sibling->right || !sibling->right ->isRed ) && (sibling->left || !sibling->left ->isRed )){
330
+
331
+ if ((!sibling->right || !sibling->right ->isRed ) && (!sibling->left || !sibling->left ->isRed )){
285
332
sibling->isRed = true ;
286
333
node = node->parent ;
287
334
} else {
288
335
if (!sibling->left || !sibling->left ->isRed ) {
289
336
if (sibling->right ) sibling->right ->isRed = false ;
290
337
sibling->isRed = true ;
291
- RotateRight (sibling);
338
+ RotateLeft (sibling);
292
339
sibling = node->parent ->left ;
293
340
}
294
341
sibling->isRed = node->parent ->isRed ;
295
342
node->parent ->isRed = false ;
296
343
sibling->left ->isRed = false ;
297
- RotateLeft (node->parent );
344
+ RotateRight (node->parent );
298
345
node = root;
299
346
}
300
347
}
348
+
349
+ if (replaceChange){
350
+ replaceChange = false ;
351
+ if (replacingNode->parent ->left == replacingNode){
352
+ replacingNode->parent ->left = nullptr ;
353
+ delete replacingNode;
354
+ } else if (replacingNode->parent ->right == replacingNode) {
355
+ replacingNode->parent ->right = nullptr ;
356
+ delete replacingNode;
357
+ }
358
+ }
359
+ if (siblingChange){
360
+ siblingChange = false ;
361
+ if (siblingNode->parent ->left == siblingNode){
362
+ siblingNode->parent ->left = nullptr ;
363
+ delete siblingNode;
364
+ } else if (siblingNode->parent ->right == siblingNode){
365
+ siblingNode->parent ->right = nullptr ;
366
+ delete siblingNode;
367
+ }
368
+ }
301
369
}
302
- if (node) node->isRed = false ;
370
+
371
+ node->isRed = false ;
303
372
}
304
373
305
374
void RBTree::InOrderWalk (Node *node) {
306
- // if (!node) std::cout << "nil" << std::endl;
375
+ if (!node) std::cout << " nil" << std::endl;
307
376
if (node != nullptr ) {
308
377
309
- // std::cout << node->key << "'s left: ";
378
+ std::cout << node->key << " 's left: " ;
310
379
InOrderWalk (node->left );
311
380
std::cout << node->key << " \t " << (node->isRed ? " Red" : " Black" ) << std::endl;
312
- // std::cout << node->key << "'s right: ";
381
+ std::cout << node->key << " 's right: " ;
313
382
InOrderWalk (node->right );
314
383
}
315
384
}
@@ -330,40 +399,21 @@ RBTree::RBTree() {
330
399
331
400
332
401
int main () {
333
- /* RBTree tree;
402
+ RBTree tree;
334
403
Node *arr[15 ] = {new Node (974 ), new Node (834 ), new Node (204 ), new Node (463 ), new Node (332 ),
335
404
new Node (293 ), new Node (706 ), new Node (126 ), new Node (980 ), new Node (630 ),
336
405
new Node (718 ), new Node (760 ), new Node (76 ), new Node (607 ), new Node (805 )};
337
406
338
- for (int i = 0; i < 15; i++){
339
- arr[i] = new Node((rand() % 1000 + 1));
340
- }
341
-
342
- for (int i = 0; i < 15; i++){
407
+ for (int i = 0 ; i < 15 ; i++){
343
408
tree.Insert (arr[i]);
344
409
}
345
410
346
- std::cout << "Array" << std::endl;
347
- for (int i = 0; i < 15; i++){
348
- std::cout << arr[i]->key << "\t";
349
- }
350
- std::cout << std::endl;
351
-
352
- std::cout << "Tree" << std::endl;
353
- tree.InOrderWalk(tree.root);
354
-
355
- std::cout << "Deleting: " << arr[0]->key << " and " << arr[3]->key << std::endl;
356
- tree.Delete(arr[0]);
411
+ std::cout << " Tree:\n " ;
357
412
358
413
tree.Delete (arr[3 ]);
359
- std::cout << "Tree After Delete 1:" << std::endl;
360
- tree.InOrderWalk(tree.root);
361
414
tree.Delete (arr[1 ]);
362
- std::cout << "Tree After Delete 2:" << std::endl;
363
- tree.InOrderWalk(tree.root);
364
415
tree.Delete (arr[11 ]);
365
- std::cout << "Tree After Delete 3:\n\n" << std::endl;
366
- tree.InOrderWalk(tree.root);*/
416
+ tree.InOrderWalk (tree.root );
367
417
368
418
return 0 ;
369
419
}
0 commit comments