Wednesday, May 20, 2015

Red and Black Tree in C++

RED AND BLACK TREE:

All the case's of Insertion Deletion , Searching and Display " 
Using typedef and Structure user define data types.
Code in C++

↓↓↓↓↓↓↓
Code is Bellow ☺ ☻ ↓↓↓↓↓↓
↓↓↓↓↓↓


Source code:
Programming Seekerz :  ☺


#include <iostream.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>

enum rbtree_node_color { RED, BLACK };

typedef struct rbtree_node_t {
    void* key;
    void* value;
    struct rbtree_node_t* left;
    struct rbtree_node_t* right;
    struct rbtree_node_t* parent;
    enum rbtree_node_color color;
} *rbtree_node;

typedef struct rbtree_t {
    rbtree_node root;
} *rbtree;

typedef int (*compare_func)(void* left, void* right);

rbtree rbtree_create();

void* rbtree_lookup(rbtree t, void* key, compare_func compare);
void rbtree_insert(rbtree t, void* key, void* value, compare_func compare);
void rbtree_delete(rbtree t, void* key, compare_func compare);

typedef rbtree_node node;
typedef enum rbtree_node_color color;

static node grandparent(node n);
static node sibling(node n);
static node uncle(node n);
static void verify_properties(rbtree t);
static void verify_property_1(node root);
static void verify_property_2(node root);
static color node_color(node n);
static void verify_property_4(node root);
static void verify_property_5(node root);
static void verify_property_5_helper(node n, int black_count, int* black_count_path);

static node new_node(void* key, void* value, color node_color, node left, node right);
static node lookup_node(rbtree t, void* key, compare_func compare);
static void rotate_left(rbtree t, node n);
static void rotate_right(rbtree t, node n);

static void replace_node(rbtree t, node oldn, node newn);
static void insert_case1(rbtree t, node n);
static void insert_case2(rbtree t, node n);
static void insert_case3(rbtree t, node n);
static void insert_case4(rbtree t, node n);
static void insert_case5(rbtree t, node n);
static node maximum_node(node root);
static void delete_case1(rbtree t, node n);
static void delete_case2(rbtree t, node n);
static void delete_case3(rbtree t, node n);
static void delete_case4(rbtree t, node n);
static void delete_case5(rbtree t, node n);
static void delete_case6(rbtree t, node n);

node grandparent(node n) {
    //assert (n != NULL);
    //assert (n->parent != NULL); /* Not the root node */
    //assert (n->parent->parent != NULL); /* Not child of root */
    return n->parent->parent;
}
node sibling(node n) {
    //assert (n != NULL);
    //assert (n->parent != NULL); /* Root node has no sibling */
    if (n == n->parent->left)
        return n->parent->right;
    else
        return n->parent->left;
}
node uncle(node n) {
    //assert (n != NULL);
    //assert (n->parent != NULL); /* Root node has no uncle */
    //assert (n->parent->parent != NULL); /* Children of root have no uncle */
    return sibling(n->parent);
}
void verify_properties(rbtree t) {

    verify_property_1(t->root);
    verify_property_2(t->root);
    /* Property 3 is implicit */
    verify_property_4(t->root);
    verify_property_5(t->root);
t;
}
void verify_property_1(node n) {
    //assert(node_color(n) == RED || node_color(n) == BLACK);
    if (n == NULL) return;
    verify_property_1(n->left);
    verify_property_1(n->right);
}
void verify_property_2(node root) {
root;    //assert(node_color(root) == BLACK);
}
color node_color(node n) {
    return n == NULL ? BLACK : n->color;
}
void verify_property_4(node n) {
    if (node_color(n) == RED) {
//assert (node_color(n->left)   == BLACK);
//assert (node_color(n->right)  == BLACK);
//assert (node_color(n->parent) == BLACK);
    }
    if (n == NULL) return;
    verify_property_4(n->left);
    verify_property_4(n->right);
}
void verify_property_5(node root) {
    int black_count_path = -1;
    verify_property_5_helper(root, 0, &black_count_path);
}

void verify_property_5_helper(node n, int black_count, int* path_black_count) {
    if (node_color(n) == BLACK) {
        black_count++;
    }
    if (n == NULL) {
        if (*path_black_count == -1) {
            *path_black_count = black_count;
        } else {
   //assert (black_count == *path_black_count);
        }
        return;
    }
    verify_property_5_helper(n->left,  black_count, path_black_count);
    verify_property_5_helper(n->right, black_count, path_black_count);
}
rbtree rbtree_create() {
    rbtree t= new rbtree_t();
    t->root = NULL;
    verify_properties(t);
    return t;
}
node new_node(void* key, void* value, color node_color, node left, node right) {
    node newnode=new rbtree_node_t();
    newnode->key = key;
    newnode->value = value;
    newnode->color = node_color;
    newnode->left = left;
    newnode->right = right;
    if (left  != NULL)  left->parent = newnode;
    if (right != NULL) right->parent = newnode;
    newnode->parent = NULL;
    return newnode;
}
node lookup_node(rbtree t, void* key, compare_func compare) {
    node n = t->root;
    while (n != NULL) {
int comp_newnode = compare(key, n->key);
if (comp_newnode == 0) {
            return n;
} else if (comp_newnode < 0) {
            n = n->left;
        } else {
   //assert(comp_newnode > 0);
            n = n->right;
        }
    }
    return n;
}
void* rbtree_lookup(rbtree t, void* key, compare_func compare) {
    node n = lookup_node(t, key, compare);
    return n == NULL ? NULL : n->value;
}
void rotate_left(rbtree t, node n) {
    node r = n->right;
    replace_node(t, n, r);
    n->right = r->left;
    if (r->left != NULL) {
        r->left->parent = n;
    }
    r->left = n;
    n->parent = r;
}

void rotate_right(rbtree t, node n) {
    node L = n->left;
    replace_node(t, n, L);
    n->left = L->right;
    if (L->right != NULL) {
        L->right->parent = n;
    }
    L->right = n;
    n->parent = L;
}
void replace_node(rbtree t, node oldn, node newn) {
    if (oldn->parent == NULL) {
        t->root = newn;
    } else {
        if (oldn == oldn->parent->left)
            oldn->parent->left = newn;
        else
            oldn->parent->right = newn;
    }
    if (newn != NULL) {
        newn->parent = oldn->parent;
    }
}
void rbtree_insert(rbtree t, void* key, void* value, compare_func compare) {
    node inserted_node = new_node(key, value, RED, NULL, NULL);
    if (t->root == NULL) {
        t->root = inserted_node;
    } else {
        node n = t->root;
        while (1) {
   int comp_newnode = compare(key, n->key);
   if (comp_newnode == 0) {
                n->value = value;
                return;
   } else if (comp_newnode < 0) {
                if (n->left == NULL) {
                    n->left = inserted_node;
                    break;
                } else {
                    n = n->left;
}
            } else {
//assert (comp_newnode > 0);
                if (n->right == NULL) {
                    n->right = inserted_node;
                    break;
                } else {
                    n = n->right;
                }
            }
        }
        inserted_node->parent = n;
    }
    insert_case1(t, inserted_node);
    verify_properties(t);
}
void insert_case1(rbtree t, node n) {
    if (n->parent == NULL)
        n->color = BLACK;
    else
        insert_case2(t, n);
}
void insert_case2(rbtree t, node n) {
    if (node_color(n->parent) == BLACK)
        return; /* Tree is still valid */
    else
        insert_case3(t, n);
}
void insert_case3(rbtree t, node n) {
    if (node_color(uncle(n)) == RED) {
        n->parent->color = BLACK;
        uncle(n)->color = BLACK;
        grandparent(n)->color = RED;
        insert_case1(t, grandparent(n));
    } else {
        insert_case4(t, n);
    }
}
void insert_case4(rbtree t, node n) {
    if (n == n->parent->right && n->parent == grandparent(n)->left) {
        rotate_left(t, n->parent);
        n = n->left;
    } else if (n == n->parent->left && n->parent == grandparent(n)->right)
{
        rotate_right(t, n->parent);
        n = n->right;
    }
    insert_case5(t, n);
}
void insert_case5(rbtree t, node n) {
    n->parent->color = BLACK;
    grandparent(n)->color = RED;
    if (n == n->parent->left && n->parent == grandparent(n)->left)
 {
        rotate_right(t, grandparent(n));
    } else {
//assert (n == n->parent->right && n->parent == grandparent(n)->right);
        rotate_left(t, grandparent(n));
    }
}
void rbtree_delete(rbtree t, void* key, compare_func compare) {
    node child;
    node n = lookup_node(t, key, compare);
    if (n == NULL) return;  /* Key not found, do nothing */
    if (n->left != NULL && n->right != NULL) {
        /* Copy key/value from predecessor and then delete it instead */
        node pred = maximum_node(n->left);
        n->key   = pred->key;
        n->value = pred->value;
        n = pred;
    }

    //assert(n->left == NULL || n->right == NULL);
    child = n->right == NULL ? n->left  : n->right;
    if (node_color(n) == BLACK) {
        n->color = node_color(child);
        delete_case1(t, n);
    }
    replace_node(t, n, child);
    if (n->parent == NULL && child != NULL) // root should be black
        child->color = BLACK;
//    free(n);

    verify_properties(t);
}
static node maximum_node(node n) {
    //assert (n != NULL);
    while (n->right != NULL) {
        n = n->right;
    }
    return n;
}
void delete_case1(rbtree t, node n) {
    if (n->parent == NULL)
        return;
    else
        delete_case2(t, n);
}
void delete_case2(rbtree t, node n) {
    if (node_color(sibling(n)) == RED) {
        n->parent->color = RED;
        sibling(n)->color = BLACK;
        if (n == n->parent->left)
            rotate_left(t, n->parent);
        else
            rotate_right(t, n->parent);
    }
    delete_case3(t, n);
}
void delete_case3(rbtree t, node n) {
    if (node_color(n->parent) == BLACK &&
        node_color(sibling(n)) == BLACK &&
        node_color(sibling(n)->left) == BLACK &&
        node_color(sibling(n)->right) == BLACK)
    {
        sibling(n)->color = RED;
        delete_case1(t, n->parent);
    }
    else
        delete_case4(t, n);
}
void delete_case4(rbtree t, node n) {
    if (node_color(n->parent) == RED &&
        node_color(sibling(n)) == BLACK &&
        node_color(sibling(n)->left) == BLACK &&
        node_color(sibling(n)->right) == BLACK)
    {
        sibling(n)->color = RED;
        n->parent->color = BLACK;
    }
    else
        delete_case5(t, n);
}
void delete_case5(rbtree t, node n) {
    if (n == n->parent->left &&
        node_color(sibling(n)) == BLACK &&
        node_color(sibling(n)->left) == RED &&
        node_color(sibling(n)->right) == BLACK)
    {
        sibling(n)->color = RED;
        sibling(n)->left->color = BLACK;
        rotate_right(t, sibling(n));
    }
    else if (n == n->parent->right &&
             node_color(sibling(n)) == BLACK &&
             node_color(sibling(n)->right) == RED &&
             node_color(sibling(n)->left) == BLACK)
    {
        sibling(n)->color = RED;
        sibling(n)->right->color = BLACK;
        rotate_left(t, sibling(n));
    }
    delete_case6(t, n);
}
void delete_case6(rbtree t, node n) {
    sibling(n)->color = node_color(n->parent);
    n->parent->color = BLACK;
    if (n == n->parent->left) {
//assert (node_color(sibling(n)->right) == RED);
        sibling(n)->right->color = BLACK;
        rotate_left(t, n->parent);
    }
    else
    {
//assert (node_color(sibling(n)->left) == RED);
        sibling(n)->left->color = BLACK;
        rotate_right(t, n->parent);
    }
}

static int compare_int(void* left, void* right);
static void print_tree(rbtree t);
static void print_tree_helper(rbtree_node n, int indent);

int compare_int(void* leftp, void* rightp) {
    int left = (int)leftp;
    int right = (int)rightp;
    if (left < right)
        return -1;
    else if (left > right)
        return 1;
    else {
//assert (left == right);
        return 0;
    }
}

#define INDENT_STEP  4

void print_tree_helper(rbtree_node n, int indent);

void print_tree(rbtree t) {
    print_tree_helper(t->root, 0);
    puts(" ");
}

void print_tree_helper(rbtree_node n, int indent) {
    int i;
    if (n == NULL) {
cout<<"\n\n \t\t --< Empty tree >--\n\n ";
return;
    }
    if (n->right != NULL) {
print_tree_helper(n->right, indent + INDENT_STEP);
    }
    for(i=0; i<indent; i++)
      cout<<" ";
    if (n->color == BLACK)
printf(" Black: %d\n", (int)n->key);
    else
printf(" Red= %d\n", (int)n->key);
    if (n->left != NULL) {
print_tree_helper(n->left, indent + INDENT_STEP);
    }
}
static int x=0;
int search1(rbtree_node n,int value) {
    int i;
    if (n == NULL) {
cout<<"\n\n \t\t --< Empty tree >--\n\n ";
return 0;
    }
    if (n->right != NULL) {
search1(n->right,value);
    }
if(value==(int)n->key){
    cout<<" \n Node is Found \n";
    if (n->color == BLACK)
printf("\nColor:: Black= %d\n", (int)n->key);
    else
printf("\nColor:: Red= %d\n", (int)n->key);
x=32;
return 0; }
    if (n->left != NULL) {
search1(n->left,value);
    }
return 0;
      }

    void search(rbtree t,int v) {
    search1(t->root, v);if( x != 32 )cout<<"\n\nNot Found...\n";
x=0;    }

void main() {

    int i,x,y,c=0;
    rbtree tree = rbtree_create();
while(!0){
    cout<<"\n============================================\n";
    cout<<"\n\nChoose Any Of Following Option:\n\n\n\t\t[ 1 for Insertion]\n\t\t";
cout<<"[ 2 for Deletion ]\n\t\t[ 3 for Display  ]\n\t\t[ 4 For Searching]\n\t\t[ 5 For Exit     ]\n\n";
    cin>>c;
    cout<<"\n============================================\n";
    switch(c){
    case 1:{
    cout<<"\n\nHow Many Values You Want To Insert: ";
    cin>>y;
    for(i=0; i<y; i++) {
    cout<<"\n Insert Value For insertion: ";
    cin>>x;
int y = rand() % 10000;
printf("\nInserting value is=  %d \n\n", x);
rbtree_insert(tree, (void*)x, (void*)y, compare_int);
}      break;    }
    case 2:{
cout<<" \n Enter Value For Deletion: ";
cin>>x;
printf("Deleting key %d\n\n", x);
rbtree_delete(tree, (void*)x, compare_int);
      break; }
    case 3:{
    print_tree(tree);
    break;
    }
    case 4:{
    cout<<"\n\nEnter A value for search: ";
    cin>>x;
    search(tree,x);
    break;}
    case 5:{
    exit(0);
    }
    default:{break;}
    }

}
}

Share this

0 Comment to "Red and Black Tree in C++"