map almost done
This commit is contained in:
parent
495083caba
commit
4ff8386a85
@ -1,440 +0,0 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* red_black_tree.hpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/11/27 19:52:16 by apommier #+# #+# */
|
||||
/* Updated: 2022/11/27 19:52:18 by apommier ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
// Implementing Red-Black Tree in C++
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
struct Node {
|
||||
int data;
|
||||
Node *parent;
|
||||
Node *left;
|
||||
Node *right;
|
||||
int color;
|
||||
};
|
||||
|
||||
typedef Node *NodePtr;
|
||||
|
||||
class RedBlackTree {
|
||||
private:
|
||||
NodePtr root;
|
||||
NodePtr TNULL;
|
||||
|
||||
void initializeNULLNode(NodePtr node, NodePtr parent) {
|
||||
node->data = 0;
|
||||
node->parent = parent;
|
||||
node->left = nullptr;
|
||||
node->right = nullptr;
|
||||
node->color = 0;
|
||||
}
|
||||
|
||||
// Preorder
|
||||
void preOrderHelper(NodePtr node) {
|
||||
if (node != TNULL) {
|
||||
cout << node->data << " ";
|
||||
preOrderHelper(node->left);
|
||||
preOrderHelper(node->right);
|
||||
}
|
||||
}
|
||||
|
||||
// Inorder
|
||||
void inOrderHelper(NodePtr node) {
|
||||
if (node != TNULL) {
|
||||
inOrderHelper(node->left);
|
||||
cout << node->data << " ";
|
||||
inOrderHelper(node->right);
|
||||
}
|
||||
}
|
||||
|
||||
// Post order
|
||||
void postOrderHelper(NodePtr node) {
|
||||
if (node != TNULL) {
|
||||
postOrderHelper(node->left);
|
||||
postOrderHelper(node->right);
|
||||
cout << node->data << " ";
|
||||
}
|
||||
}
|
||||
|
||||
NodePtr searchTreeHelper(NodePtr node, int key) {
|
||||
if (node == TNULL || key == node->data) {
|
||||
return node;
|
||||
}
|
||||
|
||||
if (key < node->data) {
|
||||
return searchTreeHelper(node->left, key);
|
||||
}
|
||||
return searchTreeHelper(node->right, key);
|
||||
}
|
||||
|
||||
// For balancing the tree after deletion
|
||||
void deleteFix(NodePtr x) {
|
||||
NodePtr s;
|
||||
while (x != root && x->color == 0) {
|
||||
if (x == x->parent->left) {
|
||||
s = x->parent->right;
|
||||
if (s->color == 1) {
|
||||
s->color = 0;
|
||||
x->parent->color = 1;
|
||||
leftRotate(x->parent);
|
||||
s = x->parent->right;
|
||||
}
|
||||
|
||||
if (s->left->color == 0 && s->right->color == 0) {
|
||||
s->color = 1;
|
||||
x = x->parent;
|
||||
} else {
|
||||
if (s->right->color == 0) {
|
||||
s->left->color = 0;
|
||||
s->color = 1;
|
||||
rightRotate(s);
|
||||
s = x->parent->right;
|
||||
}
|
||||
|
||||
s->color = x->parent->color;
|
||||
x->parent->color = 0;
|
||||
s->right->color = 0;
|
||||
leftRotate(x->parent);
|
||||
x = root;
|
||||
}
|
||||
} else {
|
||||
s = x->parent->left;
|
||||
if (s->color == 1) {
|
||||
s->color = 0;
|
||||
x->parent->color = 1;
|
||||
rightRotate(x->parent);
|
||||
s = x->parent->left;
|
||||
}
|
||||
|
||||
if (s->right->color == 0 && s->right->color == 0) {
|
||||
s->color = 1;
|
||||
x = x->parent;
|
||||
} else {
|
||||
if (s->left->color == 0) {
|
||||
s->right->color = 0;
|
||||
s->color = 1;
|
||||
leftRotate(s);
|
||||
s = x->parent->left;
|
||||
}
|
||||
|
||||
s->color = x->parent->color;
|
||||
x->parent->color = 0;
|
||||
s->left->color = 0;
|
||||
rightRotate(x->parent);
|
||||
x = root;
|
||||
}
|
||||
}
|
||||
}
|
||||
x->color = 0;
|
||||
}
|
||||
|
||||
void rbTransplant(NodePtr u, NodePtr v) {
|
||||
if (u->parent == nullptr) {
|
||||
root = v;
|
||||
} else if (u == u->parent->left) {
|
||||
u->parent->left = v;
|
||||
} else {
|
||||
u->parent->right = v;
|
||||
}
|
||||
v->parent = u->parent;
|
||||
}
|
||||
|
||||
void deleteNodeHelper(NodePtr node, int key) {
|
||||
NodePtr z = TNULL;
|
||||
NodePtr x, y;
|
||||
while (node != TNULL) {
|
||||
if (node->data == key) {
|
||||
z = node;
|
||||
}
|
||||
|
||||
if (node->data <= key) {
|
||||
node = node->right;
|
||||
} else {
|
||||
node = node->left;
|
||||
}
|
||||
}
|
||||
|
||||
if (z == TNULL) {
|
||||
cout << "Key not found in the tree" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
y = z;
|
||||
int y_original_color = y->color;
|
||||
if (z->left == TNULL) {
|
||||
x = z->right;
|
||||
rbTransplant(z, z->right);
|
||||
} else if (z->right == TNULL) {
|
||||
x = z->left;
|
||||
rbTransplant(z, z->left);
|
||||
} else {
|
||||
y = minimum(z->right);
|
||||
y_original_color = y->color;
|
||||
x = y->right;
|
||||
if (y->parent == z) {
|
||||
x->parent = y;
|
||||
} else {
|
||||
rbTransplant(y, y->right);
|
||||
y->right = z->right;
|
||||
y->right->parent = y;
|
||||
}
|
||||
|
||||
rbTransplant(z, y);
|
||||
y->left = z->left;
|
||||
y->left->parent = y;
|
||||
y->color = z->color;
|
||||
}
|
||||
delete z;
|
||||
if (y_original_color == 0) {
|
||||
deleteFix(x);
|
||||
}
|
||||
}
|
||||
|
||||
// For balancing the tree after insertion
|
||||
void insertFix(NodePtr k) {
|
||||
NodePtr u;
|
||||
while (k->parent->color == 1) {
|
||||
if (k->parent == k->parent->parent->right) {
|
||||
u = k->parent->parent->left;
|
||||
if (u->color == 1) {
|
||||
u->color = 0;
|
||||
k->parent->color = 0;
|
||||
k->parent->parent->color = 1;
|
||||
k = k->parent->parent;
|
||||
} else {
|
||||
if (k == k->parent->left) {
|
||||
k = k->parent;
|
||||
rightRotate(k);
|
||||
}
|
||||
k->parent->color = 0;
|
||||
k->parent->parent->color = 1;
|
||||
leftRotate(k->parent->parent);
|
||||
}
|
||||
} else {
|
||||
u = k->parent->parent->right;
|
||||
|
||||
if (u->color == 1) {
|
||||
u->color = 0;
|
||||
k->parent->color = 0;
|
||||
k->parent->parent->color = 1;
|
||||
k = k->parent->parent;
|
||||
} else {
|
||||
if (k == k->parent->right) {
|
||||
k = k->parent;
|
||||
leftRotate(k);
|
||||
}
|
||||
k->parent->color = 0;
|
||||
k->parent->parent->color = 1;
|
||||
rightRotate(k->parent->parent);
|
||||
}
|
||||
}
|
||||
if (k == root) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
root->color = 0;
|
||||
}
|
||||
|
||||
void printHelper(NodePtr root, string indent, bool last) {
|
||||
if (root != TNULL) {
|
||||
cout << indent;
|
||||
if (last) {
|
||||
cout << "R----";
|
||||
indent += " ";
|
||||
} else {
|
||||
cout << "L----";
|
||||
indent += "| ";
|
||||
}
|
||||
|
||||
string sColor = root->color ? "RED" : "BLACK";
|
||||
cout << root->data << "(" << sColor << ")" << endl;
|
||||
printHelper(root->left, indent, false);
|
||||
printHelper(root->right, indent, true);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
RedBlackTree() {
|
||||
TNULL = new Node;
|
||||
TNULL->color = 0;
|
||||
TNULL->left = nullptr;
|
||||
TNULL->right = nullptr;
|
||||
root = TNULL;
|
||||
}
|
||||
|
||||
void preorder() {
|
||||
preOrderHelper(this->root);
|
||||
}
|
||||
|
||||
void inorder() {
|
||||
inOrderHelper(this->root);
|
||||
}
|
||||
|
||||
void postorder() {
|
||||
postOrderHelper(this->root);
|
||||
}
|
||||
|
||||
NodePtr searchTree(int k) {
|
||||
return searchTreeHelper(this->root, k);
|
||||
}
|
||||
|
||||
NodePtr minimum(NodePtr node) {
|
||||
while (node->left != TNULL) {
|
||||
node = node->left;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
NodePtr maximum(NodePtr node) {
|
||||
while (node->right != TNULL) {
|
||||
node = node->right;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
NodePtr successor(NodePtr x) {
|
||||
if (x->right != TNULL) {
|
||||
return minimum(x->right);
|
||||
}
|
||||
|
||||
NodePtr y = x->parent;
|
||||
while (y != TNULL && x == y->right) {
|
||||
x = y;
|
||||
y = y->parent;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
NodePtr predecessor(NodePtr x) {
|
||||
if (x->left != TNULL) {
|
||||
return maximum(x->left);
|
||||
}
|
||||
|
||||
NodePtr y = x->parent;
|
||||
while (y != TNULL && x == y->left) {
|
||||
x = y;
|
||||
y = y->parent;
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
void leftRotate(NodePtr x) {
|
||||
NodePtr y = x->right;
|
||||
x->right = y->left;
|
||||
if (y->left != TNULL) {
|
||||
y->left->parent = x;
|
||||
}
|
||||
y->parent = x->parent;
|
||||
if (x->parent == nullptr) {
|
||||
this->root = y;
|
||||
} else if (x == x->parent->left) {
|
||||
x->parent->left = y;
|
||||
} else {
|
||||
x->parent->right = y;
|
||||
}
|
||||
y->left = x;
|
||||
x->parent = y;
|
||||
}
|
||||
|
||||
void rightRotate(NodePtr x) {
|
||||
NodePtr y = x->left;
|
||||
x->left = y->right;
|
||||
if (y->right != TNULL) {
|
||||
y->right->parent = x;
|
||||
}
|
||||
y->parent = x->parent;
|
||||
if (x->parent == nullptr) {
|
||||
this->root = y;
|
||||
} else if (x == x->parent->right) {
|
||||
x->parent->right = y;
|
||||
} else {
|
||||
x->parent->left = y;
|
||||
}
|
||||
y->right = x;
|
||||
x->parent = y;
|
||||
}
|
||||
|
||||
// Inserting a node
|
||||
void insert(int key)
|
||||
{
|
||||
NodePtr node = new Node;
|
||||
node->parent = nullptr;
|
||||
node->data = key;
|
||||
node->left = TNULL;
|
||||
node->right = TNULL;
|
||||
node->color = 1;
|
||||
|
||||
NodePtr y = nullptr;
|
||||
NodePtr x = this->root;
|
||||
|
||||
while (x != TNULL) {
|
||||
y = x;
|
||||
if (node->data < x->data)
|
||||
{
|
||||
x = x->left;
|
||||
} else {
|
||||
x = x->right;
|
||||
}
|
||||
}
|
||||
|
||||
node->parent = y;
|
||||
if (y == nullptr) {
|
||||
root = node;
|
||||
} else if (node->data < y->data) {
|
||||
y->left = node;
|
||||
} else {
|
||||
y->right = node;
|
||||
}
|
||||
|
||||
if (node->parent == nullptr) {
|
||||
node->color = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (node->parent->parent == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
insertFix(node);
|
||||
}
|
||||
|
||||
NodePtr getRoot() {
|
||||
return this->root;
|
||||
}
|
||||
|
||||
void deleteNode(int data) {
|
||||
deleteNodeHelper(this->root, data);
|
||||
}
|
||||
|
||||
void printTree() {
|
||||
if (root) {
|
||||
printHelper(this->root, "", true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
RedBlackTree bst;
|
||||
bst.insert(55);
|
||||
bst.insert(40);
|
||||
bst.insert(65);
|
||||
bst.insert(60);
|
||||
bst.insert(75);
|
||||
bst.insert(57);
|
||||
|
||||
bst.printTree();
|
||||
cout << endl
|
||||
<< "After deleting" << endl;
|
||||
bst.deleteNode(40);
|
||||
bst.printTree();
|
||||
}
|
||||
@ -291,10 +291,14 @@ class map
|
||||
//-------------------------
|
||||
ft::pair<iterator,bool> insert (const value_type& val)
|
||||
{
|
||||
iterator find = this->find(val.first);
|
||||
if (find.base() != _end)
|
||||
return (ft::make_pair(find, false));
|
||||
NodePtr pt = new_node(val.first, val.second);
|
||||
insert(pt);
|
||||
//fixViolation(_root, pt);
|
||||
_size++;
|
||||
return (ft::make_pair(iterator(_root, _end, pt), true));
|
||||
}
|
||||
|
||||
iterator insert (iterator position, const value_type& val)
|
||||
@ -304,6 +308,7 @@ class map
|
||||
insert(pt);
|
||||
//fixViolation(_root, pt);
|
||||
_size++;
|
||||
return (iterator(_root, _end, pt));
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
@ -855,8 +860,13 @@ class map
|
||||
y = x;
|
||||
if (node->data.first < x->data.first)
|
||||
x = x->left;
|
||||
else
|
||||
else if (node->data.first > x->data.first)
|
||||
x = x->right;
|
||||
else
|
||||
{
|
||||
_size--;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
node->parent = y;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user