红黑树

红黑树数据结构

#ifndef __RED_BLACK_TREE_H
#define __RED_BLACK_TREE_H

#define RED 1
#define BLACK 0

typedef struct Red_Black_Node
{
    int id;
    int color;
    int key;
    struct Red_Black_Node* left;
    struct Red_Black_Node* right;
    struct Red_Black_Node* parent;
}Red_Black_Node;

typedef struct Red_Black_Tree
{
    int count;
    Red_Black_Node* root;
    Red_Black_Node* nil;
}Red_Black_Tree;

// node
Red_Black_Node* red_black_node_create( );
void red_black_node_free(Red_Black_Node* node);
void red_black_node_copy(Red_Black_Node* dst, Red_Black_Node* src);

// tree
Red_Black_Tree* red_black_tree_create( );
void _red_black_tree_free(Red_Black_Tree* tree, Red_Black_Node* node);
void red_black_tree_free(Red_Black_Tree* tree);
void _red_black_tree_print(Red_Black_Tree* tree, Red_Black_Node* node);
void red_black_tree_print(Red_Black_Tree* tree);
void red_black_tree_insert(Red_Black_Tree* tree, Red_Black_Node* node);
void red_black_tree_insert_fixup(Red_Black_Tree* tree, Red_Black_Node* node);
void red_black_tree_transplant(Red_Black_Tree* tree, Red_Black_Node* u, Red_Black_Node* v);
void red_black_tree_delete(Red_Black_Tree* tree, Red_Black_Node* node);
void red_black_tree_delete_fixup(Red_Black_Tree* tree, Red_Black_Node* node);
void red_black_tree_left_rotate(Red_Black_Tree* tree, Red_Black_Node* node);
void red_black_tree_right_rotate(Red_Black_Tree* tree, Red_Black_Node* node);
Red_Black_Node* red_black_subtree_maximum(Red_Black_Tree* tree, Red_Black_Node* subtree);
Red_Black_Node* red_black_subtree_minimum(Red_Black_Tree* tree, Red_Black_Node* subtree);
Red_Black_Node* red_black_tree_search(Red_Black_Tree* tree, int key);
#endif

实现代码

#include <stdio.h>
#include <stdlib.h>
#include "red_black_tree.h"

// node
Red_Black_Node* red_black_node_create( )
{
    Red_Black_Node* node = (Red_Black_Node*)malloc(sizeof(Red_Black_Node));
    return node;
}
void red_black_node_free(Red_Black_Node* node)
{
    free(node);
}
void red_black_node_copy(Red_Black_Node* dst, Red_Black_Node* src)
{
    dst->color = src->color;
    dst->key = src->key;
    dst->left = src->left;
    dst->right = src->right;
    dst->parent = src->parent;
}

// tree
Red_Black_Tree* red_black_tree_create( )
{
    Red_Black_Tree* tree = (Red_Black_Tree*)malloc(sizeof(Red_Black_Tree));
    tree->nil = red_black_node_create( );
    tree->nil->id = -1;
    tree->nil->color = BLACK;
    tree->nil->key = 0;
    tree->nil->left = NULL;
    tree->nil->right = NULL;
    tree->nil->parent = NULL;
    tree->root = tree->nil;
    tree->count = 0;
        
    return tree;
}

void red_black_tree_print(Red_Black_Tree* tree)
{
    _red_black_tree_print(tree, tree->root);
    printf("\n");
}

void _red_black_tree_print(Red_Black_Tree* tree, Red_Black_Node* node)
{
    if (node != tree->nil)
    {
        _red_black_tree_print(tree, node->left);
        printf("[id: %d, color: %s, key: %d, parent: %d, left: %d, right: %d] ", node->id, node->color == BLACK ? "BLACK" : "RED", node->key, node->parent->id, node->left->id, node->right->id);
        _red_black_tree_print(tree, node->right);
    }
}
void _red_black_tree_free(Red_Black_Tree* tree, Red_Black_Node* node)
{
    if (node != tree->nil)
    {
        _red_black_tree_free(tree, node->left);
        _red_black_tree_free(tree, node->right);
        red_black_node_free(node);
    }
}
void red_black_tree_free(Red_Black_Tree* tree)
{
    _red_black_tree_free(tree, tree->root);
    red_black_node_free(tree->nil);
    free(tree);
}
void red_black_tree_left_rotate(Red_Black_Tree* tree, Red_Black_Node* x)
{
    Red_Black_Node* y = x->right;
    x->right = y->left;
    if (y->left != tree->nil)
    {
        y->left->parent = x;
    }
    y->parent = x->parent;

    if (x->parent == tree->nil)
    {
        tree->root = y;
    }
    else if (x == x->parent->left)
    {
        x->parent->left = y;
    }
    else if (x == x->parent->right)
    {
        x->parent->right = y;
    }

    y->left = x;
    x->parent = y;
}
void red_black_tree_right_rotate(Red_Black_Tree* tree, Red_Black_Node* x)
{
    Red_Black_Node* y = x->left;
    x->left = y->right;
    if (y->right != tree->nil)
    {
        y->right->parent = x;
    }

    y->parent = x->parent;
    if (x->parent == tree->nil)
    {
        tree->root = y;
    }
    else if (x == x->parent->left)
    {
        x->parent->left = y;
    }
    else if (x == x->parent->right)
    {
        x->parent->right = y;
    }

    y->right = x;
    x->parent = y;
}

void red_black_tree_insert(Red_Black_Tree* tree, Red_Black_Node* node)
{
    // copy node to z
    Red_Black_Node* z = red_black_node_create( );
    red_black_node_copy(z, node);
    z->id = tree->count++;
    Red_Black_Node* y = tree->nil;
    Red_Black_Node* x = tree->root;
    while (x != tree->nil)
    {
        y = x;
        if (z->key < x->key)
        {
            x = x->left;
        }
        else
        {
            x = x->right;
        }
    }
    z->parent = y;
    if (y == tree->nil)
    {
        tree->root = z;
    }
    else if (z->key < y->key)
    {
        y->left = z;
    }
    else if (z->key >= y->key)
    {
        y->right = z;
    }

    z->left = tree->nil;
    z->right = tree->nil;
    z->color = RED;
    
    red_black_tree_insert_fixup(tree, z);
}
void red_black_tree_insert_fixup(Red_Black_Tree* tree, Red_Black_Node* z)
{
    Red_Black_Node* y = NULL;
    while (z->parent->color == RED)
    {
        if (z->parent == z->parent->parent->left)
        {
            /* z's parent is the left child of z's parent's parent*/
            y = z->parent->parent->right;

            if (y->color == RED)
            {
                //case 1: y.color is RED
                z->parent->color = BLACK;
                y->color = BLACK;
                z->parent->parent->color = RED;
                z = z->parent->parent;
            }
            else
            {
                // the color of z's uncle is BLACK
                // case 2
                if (z == z->parent->right) 
                {
                    z = z->parent;
                    red_black_tree_left_rotate(tree, z);
                }
                // case 3
                z->parent->color = BLACK;
                z->parent->parent->color = RED;
                red_black_tree_right_rotate(tree, z->parent->parent);
            }
        }
        else if (z->parent == z->parent->parent->right)
        {
            /* z's parent is the right child of z's parent's parent*/
            y = z->parent->parent->left;
            //case 1
            if (y->color == RED)
            {
                z->parent->color = BLACK;
                y->color = BLACK;
                z->parent->parent->color = RED;
                z = z->parent->parent;
            }
            else
            {
                // case 2
                if (z == z->parent->left)
                {
                    z = z->parent;
                    red_black_tree_right_rotate(tree, z);
                }
                // go to case 3
                z->parent->color = BLACK;
                z->parent->parent->color = RED;
                red_black_tree_left_rotate(tree, z->parent->parent);
            }
        }
        
    }
    tree->root->color = BLACK;
    
}
Red_Black_Node* red_black_subtree_maximum(Red_Black_Tree* tree, Red_Black_Node* subtree)
{
    while (subtree->right != tree->nil)
    {
        subtree = subtree->right;
    }
    return subtree;
}
Red_Black_Node* red_black_subtree_minimum(Red_Black_Tree* tree, Red_Black_Node* subtree)
{
    while (subtree->left != tree->nil)
    {
        subtree = subtree->left;
    }
    return subtree;
}
void red_black_tree_transplant(Red_Black_Tree* tree, Red_Black_Node* u, Red_Black_Node* v)
{
    if (u->parent == tree->nil)
    {
        tree->root = v;
    }
    else if (u == u->parent->left)
    {
        u->parent->left = v;
    }
    else
    {
        u->parent->right = v;
    }
    v->parent = u->parent;
}
void red_black_tree_delete(Red_Black_Tree* tree, Red_Black_Node* z)
{
    Red_Black_Node* y = z;
    Red_Black_Node* x = NULL;
    int y_original_color = y->color;
    
    if (z->left == tree->nil)
    {
        x = z->right;
        red_black_tree_transplant(tree, z, z->right);
    }
    else if (z->right == tree->nil)
    {
        x = z->left;
        red_black_tree_transplant(tree, z, z->left);
    }
    else
    {
        y = red_black_subtree_minimum(tree, z->right);
        y_original_color = y->color;
        x = y->right;

        if (y->parent == z)
        {
            x->parent = y;
        }
        else
        {
            red_black_tree_transplant(tree, y, y->right);
            y->right = z->right;
            y->right->parent = y;
        }
        red_black_tree_transplant(tree, z, y);
        y->left = z->left;
        y->left->parent = y;
        y->color = z->color;
    }

    if (y_original_color == BLACK)
    {
        red_black_tree_delete_fixup(tree, x);
    }
    /* free node z */
    red_black_node_free(z);
}
void red_black_tree_delete_fixup(Red_Black_Tree* tree, Red_Black_Node* x)
{
    Red_Black_Node* w = NULL;
    while (x != tree->root && x->color == BLACK)
    {
        // left child
        if (x == x->parent->left)
        {
            w = x->parent->right;
            if (w->color == RED)
            {
                // case 1
                w->color = BLACK;
                x->parent->color = RED;
                red_black_tree_left_rotate(tree, x->parent);
            }
            // go to case 2, 3 or 4
            if (w->left->color == BLACK && w->right->color == BLACK)
            {
                // case 2
                w->color = RED;
                x = x->parent;
            }
            else
            {
                // case 3 or 4
                if (w->right->color == BLACK)
                {
                    // case 3
                    w->left->color = BLACK;
                    w->color = RED;
                    red_black_tree_right_rotate(tree, w);
                }
                w->color = w->parent->color;
                w->parent->color = BLACK;
                w->right->color = BLACK;
                red_black_tree_left_rotate(tree, x->parent);
                x = tree->root;
            }
        }
        else if (x == x->parent->right)
        {
            // right child
            w = x->parent->left;

            if (w->color == RED)
            {
                // case 1
                w->color = BLACK;
                x->parent->color = RED;
                red_black_tree_right_rotate(tree, x->parent);
            }

            // case 2, 3 or 4
            if (w->left->color == BLACK && w->right->color == BLACK)
            {
                // case 2
                w->color = RED;
                x = x->parent;
            }
            else
            {
                if (w->left->color == BLACK)
                {
                    // case 3
                    w->right->color = BLACK;
                    w->color = RED;
                    red_black_tree_left_rotate(tree, w);
                    w = x->parent->left;
                }

                // case 4
                w->color = w->parent->color;
                x->parent->color = BLACK;
                w->left->color = BLACK;
                red_black_tree_right_rotate(tree, x->parent);
                x = tree->root;
                
            }
            
        }
    }
    x->color = BLACK;
}

Red_Black_Node* red_black_tree_search(Red_Black_Tree* tree, int key)
{
    Red_Black_Node* node = tree->root;
    while (node != tree->nil && key != node->key)
    {
        if (key < node->key)
        {
            node = node->left;
        }
        else
        {
            node = node->right;
        }
    }
    return node;
}

 

#include <stdio.h>
#include <stdlib.h>
#include "red_black_tree.h"

int main(int argc, char** argv)
{
    Red_Black_Tree* tree = red_black_tree_create( );
    Red_Black_Node* node = red_black_node_create( );
    Red_Black_Node* result = NULL;
    int i = 0;
    for (i = 0; i < 4; i++)
    {
        node->key = i;
        red_black_tree_insert(tree, node);
    }
    red_black_tree_print(tree);
    result = red_black_tree_search(tree, 1);
    printf("id: %d\n", result->id);
    red_black_tree_delete(tree, result);
    red_black_tree_print(tree);
    red_black_node_free(node);
    red_black_tree_free(tree);
    return 0;
}

 

posted @ 2014-07-31 11:33  liuzhijiang123  阅读(121)  评论(0编辑  收藏  举报