首页 > 代码库 > 红黑树

红黑树

红黑树数据结构

#ifndef __RED_BLACK_TREE_H#define __RED_BLACK_TREE_H#define RED 1#define BLACK 0typedef 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;// nodeRed_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);// treeRed_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"// nodeRed_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;}// treeRed_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;}