erase work
This commit is contained in:
parent
6708fd4926
commit
495083caba
@ -1,18 +1,18 @@
|
|||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
/* */
|
/* */
|
||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* bidirectionnal_iterator.hpp :+: :+: :+: */
|
/* bidirectionnal_iterator.hpp :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2022/11/22 14:50:53 by apommier #+# #+# */
|
/* Created: 2022/11/22 14:50:53 by apommier #+# #+# */
|
||||||
/* Updated: 2022/11/27 16:57:48 by apommier ### ########.fr */
|
/* Updated: 2022/11/27 21:22:24 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define _end 0
|
//#define _end 0
|
||||||
|
|
||||||
namespace ft
|
namespace ft
|
||||||
{
|
{
|
||||||
@ -29,17 +29,19 @@ class bidirectionnal_iterator
|
|||||||
typedef T& reference;
|
typedef T& reference;
|
||||||
typedef const T& const_reference;
|
typedef const T& const_reference;
|
||||||
typedef bidirectionnal_iterator iterator_category;
|
typedef bidirectionnal_iterator iterator_category;
|
||||||
typedef Node node_type;
|
typedef Node node;
|
||||||
|
typedef Node* NodePtr;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
node_type *_root;
|
NodePtr _root;
|
||||||
node_type *_node;
|
NodePtr _end;
|
||||||
|
NodePtr _node;
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
bidirectionnal_iterator() : _root(NULL), _node(NULL) {}
|
bidirectionnal_iterator() : _root(NULL), _end(NULL), _node(NULL) {}
|
||||||
bidirectionnal_iterator(node_type *root, node_type *node) : _root(root), _node(node) {}
|
bidirectionnal_iterator(NodePtr root, NodePtr end, NodePtr node) : _root(root), _end(end), _node(node) { /*_end = NULL*/ }
|
||||||
bidirectionnal_iterator(bidirectionnal_iterator const &rhs) { *this = rhs; }
|
bidirectionnal_iterator(bidirectionnal_iterator const &rhs) { *this = rhs; }
|
||||||
|
|
||||||
~bidirectionnal_iterator() {}
|
~bidirectionnal_iterator() {}
|
||||||
@ -49,7 +51,7 @@ class bidirectionnal_iterator
|
|||||||
if (this != &rhs)
|
if (this != &rhs)
|
||||||
{
|
{
|
||||||
this->_root = rhs._root;
|
this->_root = rhs._root;
|
||||||
//this->_end = rhs._end;
|
this->_end = rhs._end;
|
||||||
this->_node = rhs._node;
|
this->_node = rhs._node;
|
||||||
}
|
}
|
||||||
return (*this);
|
return (*this);
|
||||||
@ -57,10 +59,10 @@ class bidirectionnal_iterator
|
|||||||
|
|
||||||
operator bidirectionnal_iterator<const T, const Node>() const
|
operator bidirectionnal_iterator<const T, const Node>() const
|
||||||
{
|
{
|
||||||
return (bidirectionnal_iterator<const T, const Node>(_root, _node));
|
return (bidirectionnal_iterator<const T, const Node>(_root, _end, _node));
|
||||||
}
|
}
|
||||||
|
|
||||||
node_type *base() { return (_node); }
|
NodePtr base() { return (_node); }
|
||||||
|
|
||||||
friend bool operator==(const bidirectionnal_iterator &rhs, const bidirectionnal_iterator &lhs)
|
friend bool operator==(const bidirectionnal_iterator &rhs, const bidirectionnal_iterator &lhs)
|
||||||
{
|
{
|
||||||
@ -97,85 +99,231 @@ class bidirectionnal_iterator
|
|||||||
pointer operator->() { return (&(_node->data)); }
|
pointer operator->() { return (&(_node->data)); }
|
||||||
const_pointer operator->() const { return (&(_node->data)); }
|
const_pointer operator->() const { return (&(_node->data)); }
|
||||||
|
|
||||||
bidirectionnal_iterator &operator ++()
|
|
||||||
{
|
|
||||||
if (_node != NULL)
|
|
||||||
_node = successor(_node);
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
bidirectionnal_iterator operator ++(int)
|
|
||||||
{
|
|
||||||
bidirectionnal_iterator tmp(*this);
|
|
||||||
++(*this);
|
|
||||||
return (tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
bidirectionnal_iterator &operator --()
|
bidirectionnal_iterator &operator++() {
|
||||||
{
|
//std::cout << "end == "<< _end << std::endl;
|
||||||
if (_node == _end)
|
//std::cout << "node == "<< _node << std::endl;
|
||||||
_node = maximum(_root);
|
if (_node != _end)
|
||||||
else
|
_node = successor(_node);
|
||||||
_node = predecessor(_node);
|
return (*this);
|
||||||
return (*this);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bidirectionnal_iterator operator --(int)
|
bidirectionnal_iterator operator++(int) {
|
||||||
{
|
bidirectionnal_iterator tmp(*this);
|
||||||
bidirectionnal_iterator tmp(*this);
|
operator++();
|
||||||
--(*this);
|
return (tmp);
|
||||||
return (tmp);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
node_type *maximum(node_type *ptr)
|
bidirectionnal_iterator &operator--() {
|
||||||
{
|
if (_node == _end) {
|
||||||
while (ptr && ptr->right != _end)
|
_node = maximum(_root);
|
||||||
ptr = ptr->right;
|
}
|
||||||
return (ptr);
|
else
|
||||||
}
|
_node = predecessor(_node);
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
node_type *minimum(node_type *ptr)
|
bidirectionnal_iterator operator--(int) {
|
||||||
{
|
bidirectionnal_iterator tmp(*this);
|
||||||
while (ptr && ptr->left != _end)
|
operator--();
|
||||||
ptr = ptr->left;
|
return (tmp);
|
||||||
return (ptr);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
NodePtr maximum(NodePtr ptr) {
|
||||||
|
while (ptr->right != _end)
|
||||||
|
ptr = ptr->right;
|
||||||
|
return (ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodePtr minimum(NodePtr ptr) {
|
||||||
|
while (ptr->left != _end)
|
||||||
|
ptr = ptr->left;
|
||||||
|
return (ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodePtr predecessor(NodePtr x) {
|
||||||
|
if (x->left != _end)
|
||||||
|
{
|
||||||
|
return maximum(x->left);
|
||||||
|
}
|
||||||
|
NodePtr y = x->parent;
|
||||||
|
while (y != NULL && x == y->left)
|
||||||
|
{
|
||||||
|
x = y;
|
||||||
|
y = y->parent;
|
||||||
|
}
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
NodePtr successor(NodePtr x) {
|
||||||
|
if (x->right != _end)
|
||||||
|
return minimum(x->right);
|
||||||
|
NodePtr y = x->parent;
|
||||||
|
while (y != NULL && x == y->right)
|
||||||
|
{
|
||||||
|
x = y;
|
||||||
|
y = y->parent;
|
||||||
|
}
|
||||||
|
if (y == NULL)
|
||||||
|
return _end;
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// bidirectionnal_iterator &operator ++()
|
||||||
|
// {
|
||||||
|
// if (_node != NULL)
|
||||||
|
// _node = successor(_node);
|
||||||
|
// return (*this);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bidirectionnal_iterator operator ++(int)
|
||||||
|
// {
|
||||||
|
// bidirectionnal_iterator tmp(*this);
|
||||||
|
// ++(*this);
|
||||||
|
// return (tmp);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bidirectionnal_iterator &operator --()
|
||||||
|
// {
|
||||||
|
// if (_node == _end)
|
||||||
|
// _node = maximum(_root);
|
||||||
|
// else
|
||||||
|
// _node = predecessor(_node);
|
||||||
|
// return (*this);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bidirectionnal_iterator operator --(int)
|
||||||
|
// {
|
||||||
|
// bidirectionnal_iterator tmp(*this);
|
||||||
|
// --(*this);
|
||||||
|
// return (tmp);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// NodePtr maximum(NodePtr ptr)
|
||||||
|
// {
|
||||||
|
// while (ptr && ptr->right != _end)
|
||||||
|
// ptr = ptr->right;
|
||||||
|
// return (ptr);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// NodePtr minimum(NodePtr ptr)
|
||||||
|
// {
|
||||||
|
// while (ptr && ptr->left != _end)
|
||||||
|
// ptr = ptr->left;
|
||||||
|
// return (ptr);
|
||||||
|
// }
|
||||||
|
// NodePtr minimum(NodePtr node)
|
||||||
|
// {
|
||||||
|
// if (!node)
|
||||||
|
// return NULL;
|
||||||
|
// while (node->left->parent != NULL)
|
||||||
|
// node = node->left;
|
||||||
|
// return node;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// NodePtr maximum(NodePtr node)
|
||||||
|
// {
|
||||||
|
// if (!node)
|
||||||
|
// return NULL;
|
||||||
|
// while (node->right->parent != NULL)
|
||||||
|
// node = node->right;
|
||||||
|
// return node;
|
||||||
|
// }
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
node_type *predecessor(node_type *x)
|
// NodePtr predecessor(NodePtr x)
|
||||||
{
|
// {
|
||||||
if (x->left != _end)
|
// if (x->left != _end)
|
||||||
{
|
// {
|
||||||
return maximum(x->left);
|
// return maximum(x->left);
|
||||||
}
|
// }
|
||||||
node_type *y = x->parent;
|
// NodePtr y = x->parent;
|
||||||
while (y != NULL && x == y->left)
|
// while (y != NULL && x == y->left)
|
||||||
{
|
// {
|
||||||
x = y;
|
// x = y;
|
||||||
y = y->parent;
|
// y = y->parent;
|
||||||
}
|
// }
|
||||||
return y;
|
// return y;
|
||||||
}
|
// }
|
||||||
|
|
||||||
node_type *successor(node_type *x)
|
// NodePtr successor(NodePtr x)
|
||||||
{
|
// {
|
||||||
if (!x)
|
// if (!x)
|
||||||
return (0);
|
// return (0);
|
||||||
//std::cout << "_node: " << this->base() << std::endl;
|
// //std::cout << "_node: " << this->base() << std::endl;
|
||||||
//std::cout << "succkey: " << x->data.first << " | succvalue: " << x->data.second << std::endl;
|
// //std::cout << "succkey: " << x->data.first << " | succvalue: " << x->data.second << std::endl;
|
||||||
if (x->right != _end)
|
// if (x->right != _end)
|
||||||
return minimum(x->right);
|
// return minimum(x->right);
|
||||||
node_type *y = x->parent;
|
// NodePtr y = x->parent;
|
||||||
while (y != NULL && x == y->right)
|
// while (y != NULL && x == y->right)
|
||||||
{
|
// {
|
||||||
x = y;
|
// x = y;
|
||||||
y = y->parent;
|
// y = y->parent;
|
||||||
}
|
// }
|
||||||
if (y == NULL)
|
// if (y == NULL)
|
||||||
return _end;
|
// return _end;
|
||||||
return y;
|
// return y;
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// NodePtr successor(NodePtr x) {
|
||||||
|
// if (x->right != NULL) {
|
||||||
|
// return minimum(x->right);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// NodePtr y = x->parent;
|
||||||
|
// while (y != NULL && x == y->right) {
|
||||||
|
// x = y;
|
||||||
|
// y = y->parent;
|
||||||
|
// }
|
||||||
|
// return y;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// NodePtr predecessor(NodePtr x) {
|
||||||
|
// if (x->left != NULL) {
|
||||||
|
// return maximum(x->left);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// NodePtr y = x->parent;
|
||||||
|
// while (y != NULL && x == y->left) {
|
||||||
|
// x = y;
|
||||||
|
// y = y->parent;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return y;
|
||||||
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2022/10/30 16:14:35 by apommier #+# #+# */
|
/* Created: 2022/10/30 16:14:35 by apommier #+# #+# */
|
||||||
/* Updated: 2022/11/25 10:57:42 by apommier ### ########.fr */
|
/* Updated: 2022/11/28 13:35:24 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|||||||
440
containers/iterators/red_black_tree.hpp
Normal file
440
containers/iterators/red_black_tree.hpp
Normal file
@ -0,0 +1,440 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* 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();
|
||||||
|
}
|
||||||
1285
containers/map.hpp
1285
containers/map.hpp
File diff suppressed because it is too large
Load Diff
1274
containers/map2.hpp
Normal file
1274
containers/map2.hpp
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user