Skip to content

Commit 7f5bbb8

Browse files
committed
Delete Fix now works with null nodes
1 parent 4071cf9 commit 7f5bbb8

File tree

4 files changed

+93
-45
lines changed

4 files changed

+93
-45
lines changed

HW3/cmake-build-debug/CMakeFiles/HW3.dir/CXX.includecache

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,4 @@ iostream
1313
-
1414
hw3.h
1515
/home/ugur/Belgeler/ProgrammingProjects/AlgoI/HW3/hw3.h
16-
cstdlib
17-
-
1816

-456 Bytes
Binary file not shown.

HW3/cmake-build-debug/HW3

8 Bytes
Binary file not shown.

HW3/main.cpp

Lines changed: 93 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#include <iostream>
22
#include "hw3.h"
3-
#include <cstdlib>
43

54
class Node{
65
public:
@@ -23,13 +22,16 @@ Node::Node(int key) {
2322
class RBTree{
2423
public:
2524
Node *root;
25+
// Necessary nodes for delete fix(So we have no memory leak)
26+
Node *replacingNode;
27+
Node *siblingNode;
2628
void RotateLeft(Node *node);
2729
void RotateRight(Node *node);
2830
void Insert(Node *node);
2931
void InsertFix(Node *node);
3032
void Transplant(Node *oldNode, Node *newNode);
3133
void Delete(Node *node);
32-
void DeleteFix(Node *node);
34+
void DeleteFix(Node *node, bool rep);
3335
void InOrderWalk(Node *node);
3436
Node* TreeMinimum(Node *begin);
3537
RBTree();
@@ -219,18 +221,41 @@ void RBTree::Delete(Node *node) {
219221
Node *temp = node;
220222
Node *replace = nullptr;
221223
bool originalIsRed = temp->isRed;
224+
bool rep = false;
225+
222226
if (node->left == nullptr){
223227
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+
224239
Transplant(node, node->right);
240+
225241
} 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
227243
Transplant(node, node->left);
228244
} else {
229245
temp = TreeMinimum(node->right);
230246
originalIsRed = temp->isRed;
231247
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+
}
232257
if (temp->parent == node){
233-
if (replace) replace->parent = temp;
258+
replace->parent = temp;
234259
} else {
235260
Transplant(temp, temp->right);
236261
temp->right = node->right;
@@ -243,21 +268,33 @@ void RBTree::Delete(Node *node) {
243268
}
244269

245270
if(!(originalIsRed))
246-
DeleteFix(replace);
271+
DeleteFix(replace, rep);
247272
}
248273

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){
253282
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){
255292
sibling->isRed = false;
256293
node->parent->isRed = true;
257294
RotateLeft(node->parent);
258295
sibling = node->parent->right;
259296
}
260-
if ((!sibling->left || !sibling->left->isRed) && (!sibling->right || !sibling->right)){
297+
if ((!sibling->left || !sibling->left->isRed) && (!sibling->right || !sibling->right->isRed)){
261298
sibling->isRed = true;
262299
node = node->parent;
263300
} else {
@@ -275,41 +312,73 @@ void RBTree::DeleteFix(Node *node) {
275312
}
276313
} else {
277314
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){
279325
sibling->isRed = false;
280326
node->parent->isRed = true;
281-
RotateLeft(node->parent);
327+
RotateRight(node->parent);
282328
sibling = node->parent->left;
283329
}
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)){
285332
sibling->isRed = true;
286333
node = node->parent;
287334
} else {
288335
if (!sibling->left || !sibling->left->isRed) {
289336
if (sibling->right) sibling->right->isRed = false;
290337
sibling->isRed = true;
291-
RotateRight(sibling);
338+
RotateLeft(sibling);
292339
sibling = node->parent->left;
293340
}
294341
sibling->isRed = node->parent->isRed;
295342
node->parent->isRed = false;
296343
sibling->left->isRed = false;
297-
RotateLeft(node->parent);
344+
RotateRight(node->parent);
298345
node = root;
299346
}
300347
}
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+
}
301369
}
302-
if (node) node->isRed = false;
370+
371+
node->isRed = false;
303372
}
304373

305374
void RBTree::InOrderWalk(Node *node) {
306-
//if (!node) std::cout << "nil" << std::endl;
375+
if (!node) std::cout << "nil" << std::endl;
307376
if(node != nullptr) {
308377

309-
//std::cout << node->key << "'s left: ";
378+
std::cout << node->key << "'s left: ";
310379
InOrderWalk(node->left);
311380
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: ";
313382
InOrderWalk(node->right);
314383
}
315384
}
@@ -330,40 +399,21 @@ RBTree::RBTree() {
330399

331400

332401
int main() {
333-
/*RBTree tree;
402+
RBTree tree;
334403
Node *arr[15] = {new Node(974), new Node(834), new Node(204), new Node(463), new Node(332),
335404
new Node(293), new Node(706), new Node(126), new Node(980), new Node(630),
336405
new Node(718), new Node(760), new Node(76), new Node(607), new Node(805)};
337406

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++){
343408
tree.Insert(arr[i]);
344409
}
345410

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";
357412

358413
tree.Delete(arr[3]);
359-
std::cout << "Tree After Delete 1:" << std::endl;
360-
tree.InOrderWalk(tree.root);
361414
tree.Delete(arr[1]);
362-
std::cout << "Tree After Delete 2:" << std::endl;
363-
tree.InOrderWalk(tree.root);
364415
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);
367417

368418
return 0;
369419
}

0 commit comments

Comments
 (0)