diff --git a/build/CMakeFiles/RBlib.dir/src/Red-Black.cpp.o b/build/CMakeFiles/RBlib.dir/src/Red-Black.cpp.o index 07b5d9c..b5d0f72 100644 Binary files a/build/CMakeFiles/RBlib.dir/src/Red-Black.cpp.o and b/build/CMakeFiles/RBlib.dir/src/Red-Black.cpp.o differ diff --git a/build/CMakeFiles/main.dir/src/main.cpp.o b/build/CMakeFiles/main.dir/src/main.cpp.o index dab0bb3..fd56bd5 100644 Binary files a/build/CMakeFiles/main.dir/src/main.cpp.o and b/build/CMakeFiles/main.dir/src/main.cpp.o differ diff --git a/build/libRBlib.a b/build/libRBlib.a index f7efcf6..f6f0fcf 100644 Binary files a/build/libRBlib.a and b/build/libRBlib.a differ diff --git a/build/main b/build/main index 6b9b9d2..4b9f9ed 100755 Binary files a/build/main and b/build/main differ diff --git a/src/Red-Black.cpp b/src/Red-Black.cpp index 92991a9..e93b635 100644 --- a/src/Red-Black.cpp +++ b/src/Red-Black.cpp @@ -42,13 +42,17 @@ void RB::ins(Node* node, Node* newnode){ this -> ins(node -> get_rchild(), newnode); } + this -> cleanup(newnode); +} + +void RB::cleanup(Node* newnode){ Node* p = newnode -> get_parent(); Node* gp; while ((p != nullptr) && (p -> get_color() == red)){ gp = p -> get_parent(); if (gp == nullptr) - return; + break; if (p == (gp -> get_lchild())){ //Case 1: if (gp -> get_rchild() != nullptr && gp -> get_rchild() -> get_color() == red){ @@ -93,16 +97,18 @@ void RB::ins(Node* node, Node* newnode){ else if(newnode == p -> get_lchild()){ newnode = p; p = newnode -> get_parent(); - left_rot(newnode); + //left_rot(newnode); + right_rot(newnode); } //Case 3 else{ - p = newnode -> get_parent(); + //p = newnode -> get_parent(); gp = p -> get_parent(); p -> set_color(black); gp -> set_color(red); - right_rot(gp); + //right_rot(gp); + left_rot(gp); p = newnode -> get_parent(); } } @@ -110,7 +116,66 @@ void RB::ins(Node* node, Node* newnode){ this -> get_root() -> set_color(black); } -void RB::del(int key){ +void RB::del(Node* node, int key){ + if (key < node -> get_key()) + del(node -> get_lchild(), key); + else if (key > node -> get_key()) + del(node -> get_rchild(), key); + else if (key == node -> get_key()){ + //Case 1: No children + if (node -> get_lchild() == nullptr && node -> get_rchild() == nullptr){ + if (node -> get_parent() -> get_lchild() == node){ + Node* p = node -> get_parent(); + p -> set_lchild(nullptr); + node = p; + } + else{ + Node* p = node -> get_parent(); + p -> set_rchild(nullptr); + node = p; + } + } + //Case 2: No rchild + else if (node -> get_lchild() != nullptr && node -> get_rchild() == nullptr){ + Node* p = node -> get_parent(); + if (p -> get_lchild() == node){ + node = node -> get_lchild(); + p -> set_lchild(node); + node -> set_parent(p); + } + else{ + node = node -> get_lchild(); + p -> set_rchild(node); + node -> set_parent(p); + } + } + //Case 3: Get successor + else{ + Node* rtree = node -> get_rchild(); + Node* p = node -> get_parent(); + Node* l = node -> get_lchild(); + Node* r = node -> get_rchild(); + + bool left = (p -> get_lchild() == node); + while(node -> get_lchild() != nullptr){ + node = node -> get_lchild(); + } + if (node -> get_rchild() != nullptr){ + node -> get_parent() -> set_lchild(node -> get_rchild()); + } node -> get_rchild() -> set_parent(node -> get_parent()); + + left ? p -> set_lchild(node) : p -> set_rchild(node); + node -> set_parent(p); + node -> set_lchild(l); + node -> set_rchild(r); + } + } + else{ + std::cout << "Node does not exist in the tree" << std::endl; + return; + } + + this -> cleanup(node); } diff --git a/src/Red-Black.h b/src/Red-Black.h index 903bc1d..fb269a6 100644 --- a/src/Red-Black.h +++ b/src/Red-Black.h @@ -24,12 +24,13 @@ class RB RB(); void ins(Node* node, Node* newnode); - void del(int key); + void del(Node* node, int key); void display(Node* node, Trunk* prev, bool left); Node* get_root(); void right_rot(Node* node); void left_rot(Node* node); + void cleanup(Node* newnode); private: Node* root; diff --git a/src/main.cpp b/src/main.cpp index 341ae71..602a77c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,9 +16,48 @@ int main(int argc, char *argv[]) tree.ins(tree.get_root(), newnode); } - std::cout << "After insertion" << std::endl; + std::cout << "After insertion:" << std::endl; tree.display(tree.get_root(), nullptr, false); + std::cout << "" << std::endl; + std::cout << "Deleting 12:" << std::endl; + tree.del(tree.get_root(), 12); + tree.display(tree.get_root(), nullptr, false); + std::cout << "" << std::endl; + + std::cout << "Inserting 32:" << std::endl; + Node* newnode = new Node(32); + tree.ins(tree.get_root(), newnode); + tree.display(tree.get_root(), nullptr, false); + std::cout << "" << std::endl; + + std::cout << "Deleting 41:" << std::endl; + tree.del(tree.get_root(), 41); + tree.display(tree.get_root(), nullptr, false); + std::cout << "" << std::endl; + + RB tree2 = RB(); std::vector insert_new {834, 807, 512, 882, 127, 675, 75, 216, 822, 249, 114, 689, 625, 974, 221, 92, 374, 123, 838, 930, 654, 806, 234, 381}; + + std::cout << "Inserting initial keys from Part c..." << std::endl; + for (int k : insert_new){ + Node* newnode = new Node(k); + tree2.ins(tree2.get_root(), newnode); + } + + std::cout << "After insertion:" << std::endl; + tree2.display(tree2.get_root(), nullptr, false); + std::cout << "" << std::endl; + /* + std::cout << "Deleting 127:" << std::endl; + tree2.del(tree2.get_root(), 127); + tree2.display(tree2.get_root(), nullptr, false); + std::cout << "" << std::endl; + + std::cout << "Deleting 221:" << std::endl; + tree2.del(tree2.get_root(), 221); + tree2.display(tree2.get_root(), nullptr, false); + std::cout << "" << std::endl; + */ } \ No newline at end of file