Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Red Black Tree implementation in C++
- // Author: Algorithm Tutor
- // Tutorial URL: https://algorithmtutor.com/Data-Structures/Tree/Red-Black-Trees/
- #include <iostream>
- using namespace std;
- // data structure that represents a node in the tree
- struct Node {
- int data; // holds the key
- Node *parent; // pointer to the parent
- Node *left; // pointer to left child
- Node *right; // pointer to right child
- int color; // 1 -> Red, 0 -> Black
- };
- typedef Node *NodePtr;
- // class RBTree implements the operations in Red Black Tree
- class RBTree {
- private:
- NodePtr root;
- NodePtr TNULL;
- // initializes the nodes with appropirate values
- // all the pointers are set to point to the null pointer
- void initializeNULLNode(NodePtr node, NodePtr parent) {
- node->data = 0;
- node->parent = parent;
- node->left = nullptr;
- node->right = nullptr;
- node->color = 0;
- }
- 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);
- }
- // fix the rb tree modified by the delete operation
- void fixDelete(NodePtr x) {
- NodePtr s;
- while (x != root && x->color == 0) {
- if (x == x->parent->left) {
- s = x->parent->right;
- if (s->color == 1) {
- // case 3.1
- s->color = 0;
- x->parent->color = 1;
- leftRotate(x->parent);
- s = x->parent->right;
- }
- if (s->left->color == 0 && s->right->color == 0) {
- // case 3.2
- s->color = 1;
- x = x->parent;
- } else {
- if (s->right->color == 0) {
- // case 3.3
- s->left->color = 0;
- s->color = 1;
- rightRotate(s);
- s = x->parent->right;
- }
- // case 3.4
- 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) {
- // case 3.1
- s->color = 0;
- x->parent->color = 1;
- rightRotate(x->parent);
- s = x->parent->left;
- }
- if (s->right->color == 0 && s->right->color == 0) {
- // case 3.2
- s->color = 1;
- x = x->parent;
- } else {
- if (s->left->color == 0) {
- // case 3.3
- s->right->color = 0;
- s->color = 1;
- leftRotate(s);
- s = x->parent->left;
- }
- // case 3.4
- 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) {
- // find the node containing 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) {
- 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){
- fixDelete(x);
- }
- }
- // fix the red-black tree
- void fixInsert(NodePtr k){
- NodePtr u;
- while (k->parent->color == 1) {
- if (k->parent == k->parent->parent->right) {
- u = k->parent->parent->left; // uncle
- if (u->color == 1) {
- // case 3.1
- u->color = 0;
- k->parent->color = 0;
- k->parent->parent->color = 1;
- k = k->parent->parent;
- } else {
- if (k == k->parent->left) {
- // case 3.2.2
- k = k->parent;
- rightRotate(k);
- }
- // case 3.2.1
- k->parent->color = 0;
- k->parent->parent->color = 1;
- leftRotate(k->parent->parent);
- }
- } else {
- u = k->parent->parent->right; // uncle
- if (u->color == 1) {
- // mirror case 3.1
- u->color = 0;
- k->parent->color = 0;
- k->parent->parent->color = 1;
- k = k->parent->parent;
- } else {
- if (k == k->parent->right) {
- // mirror case 3.2.2
- k = k->parent;
- leftRotate(k);
- }
- // mirror case 3.2.1
- 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) {
- // print the tree structure on the screen
- 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);
- }
- // cout<<root->left->data<<endl;
- }
- public:
- RBTree() {
- TNULL = new Node;
- TNULL->color = 0;
- TNULL->left = nullptr;
- TNULL->right = nullptr;
- root = TNULL;
- }
- // find the node with the minimum key
- NodePtr minimum(NodePtr node) {
- while (node->left != TNULL) {
- node = node->left;
- }
- return node;
- }
- // find the node with the maximum key
- NodePtr maximum(NodePtr node) {
- while (node->right != TNULL) {
- node = node->right;
- }
- return node;
- }
- // find the successor of a given node
- // NodePtr successor(NodePtr x) {
- // // if the right subtree is not null,
- // // the successor is the leftmost node in the
- // // right subtree
- // if (x->right != TNULL) {
- // return minimum(x->right);
- // }
- //
- // // else it is the lowest ancestor of x whose
- // // left child is also an ancestor of x.
- // NodePtr y = x->parent;
- // while (y != TNULL && x == y->right) {
- // x = y;
- // y = y->parent;
- // }
- // return y;
- // }
- // find the predecessor of a given node
- // NodePtr predecessor(NodePtr x) {
- // // if the left subtree is not null,
- // // the predecessor is the rightmost node in the
- // // left subtree
- // 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;
- // }
- // rotate left at node x
- 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;
- }
- // rotate right at node x
- 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;
- }
- // insert the key to the tree in its appropriate position
- // and fix the tree
- void insert(int key) {
- // Ordinary Binary Search Insertion
- NodePtr node = new Node;
- node->parent = nullptr;
- node->data = key;
- node->left = TNULL;
- node->right = TNULL;
- node->color = 1; // new node must be red
- NodePtr y = nullptr;
- NodePtr x = this->root;
- while (x != TNULL) {
- y = x;
- if (node->data < x->data) {
- x = x->left;
- } else {
- x = x->right;
- }
- }
- // y is parent of x
- node->parent = y;
- if (y == nullptr) {
- root = node;
- } else if (node->data < y->data) {
- y->left = node;
- } else {
- y->right = node;
- }
- // if new node is a root node, simply return
- if (node->parent == nullptr){
- node->color = 0;
- return;
- }
- // if the grandparent is null, simply return
- if (node->parent->parent == nullptr) {
- return;
- }
- // Fix the tree
- fixInsert(node);
- }
- NodePtr getRoot(){
- return this->root;
- }
- // delete the node from the tree
- void deleteNode(int data) {
- deleteNodeHelper(this->root, data);
- }
- // print the tree structure on the screen
- void prettyPrint() {
- if (root) {
- printHelper(this->root, "", true);
- }
- }
- // search the tree for the key k
- // and return the corresponding node
- NodePtr searchTree(int k) {
- return searchTreeHelper(this->root, k);
- }
- };
- int main() {
- Node *node;
- RBTree bst;
- bst.insert(1);
- bst.insert(3);
- bst.insert(2);
- int n = 2;
- node = bst.searchTree(2);
- if(n!=node->data)
- {
- bst.insert(2);
- }
- bst.insert(5);
- bst.insert(7);
- bst.insert(4);
- bst.insert(6);
- bst.insert(8);
- bst.insert(10);
- bst.deleteNode(7);
- bst.deleteNode(1);
- // bst.deleteNode(8);
- bst.prettyPrint();
- return 0;
- }
Add Comment
Please, Sign In to add comment