| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 966 人关注过本帖
标题:用C++实现红黑树
只看楼主 加入收藏
meihezcl
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2007-10-28
收藏
 问题点数:0 回复次数:1 
用C++实现红黑树
哪位有用C++实现红黑树建立\插入\删除的代码,要求还能画出红黑树图形和颜色的,谢谢!
搜索更多相关主题的帖子: 图形 颜色 代码 删除 
2007-10-28 09:51
justtest
Rank: 1
等 级:新手上路
帖 子:9
专家分:0
注 册:2008-7-18
收藏
得分:0 
红黑树实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

typedef struct node
{
    int data;
    int color;
    struct node * parent;
    struct node * left;
    struct node * right;
}node_t, *node_tp;


static node_tp rb_tab_p = NULL;


void free_tab_s(node_tp node)
{
    if(!node)
        return;
    free_tab_s(node->left);
    free_tab_s(node->right);
    printf("\nfree data=%d", node->data);
    free(node);    
}

void free_tab(void)
{
    free_tab_s(rb_tab_p);
}



int node_depth(node_tp node, int * blance)
{
    int l,r;
    if(!node || !node->left || !node->right)
        return 0;
    l = node_depth(node->left, blance);
    r = node_depth(node->right,blance);

    if(l - r > 1 || l - r < -1)
    {
        printf("\n data=%d depth=%d", node->data, r - l);
        if(blance && *blance*(*blance) < (r - l)*(r-l))
            *blance = r - l;
    }
    return (l > r? l: r) + 1;
}

int travesal_mid_s(node_tp node)
{
    int l,r,depth = node_depth(node,NULL);
    if(!node || !node->left || !node->right)
        return 0;
    l = travesal_mid_s(node->left );
    printf(" %d(%d, %d) ", node->data, node->color, depth);
    r = travesal_mid_s(node->right);    
    return l + r + 1;
}

void travesal_mid(void)
{
    int count, depth, blance = 0;
    depth = node_depth(rb_tab_p, &blance);
    printf("\n---------tree is-------------\n");
    count = travesal_mid_s(rb_tab_p);
    printf("\n-----count=%d--depth=%d--blance=%d----------", count, depth, blance);
}

node_tp find_node(node_tp node, int data)
{
    if(!node || !node->left || !node->right)
        return node;
    else if(node->data > data)
        return find_node(node->left, data);
    else if(node->data < data)
        return find_node(node->right, data);
    else
        return node;
}

node_tp max_node(node_tp node)
{
    if(!node || !node->right || !node->right->right)
        return node;
    return max_node(node->right);
}

void init_node(node_tp node, int data, int color)
{
    if(!node)
        return;
    node->data = data;
    node->color = color;
    node->parent = node->left = node->right = NULL;
}

void left_rotate(node_tp node)
{
    node_tp p;
    int itmp;
    if(node && node->right)
    {
        if(node->right->color == -1 )
            node->right->right->color = -1;
        itmp = node->color;
        node->color = node->right->color;
        node->right->color = itmp;

        p = node->right;
        node->right = p->left;
        p->left = node;
    
        p->parent = node->parent;
        if(!p->parent)
            rb_tab_p = p;
        else
        {
            if(p->parent->left == node)
                p->parent->left = p;
            else
                p->parent->right = p;
        }
        node->parent = p;
        if(node->right)
            node->right->parent = node;
    }
}


void right_rotate(node_tp node)
{
    node_tp p;
    int itmp;
    if(node && node->left)
    {
        if(node->left->color == -1)
            node->left->left->color = -1;
                itmp = node->color;
                node->color = node->left->color;
                node->left->color = itmp;

        p = node->left;
        node->left = p->right;
        p->right = node;

        p->parent = node->parent;
        if(!p->parent)
            rb_tab_p = p;
        else
        {
            if(p->parent->left == node)
                p->parent->left = p;
            else
                p->parent->right = p;
        }
        node->parent = p;
        if(node->left)
            node->left->parent = node;
    }

}


void left_right_rotate(node_tp node)
{
    node_tp p;
    int itmp;
    if(node && node->left && node->left->right)
    {
                itmp = node->color;
                node->color = node->left->right->color;
                node->left->right->color = itmp;
        node->color = node->left->color;

        p = node->left->right;
        node->left->right = p->left;
        p->left = node->left;
        
        node->left = p->right;
        p->right = node;    

        p->parent = node->parent;
        if(!p->parent)
            rb_tab_p = p;
        else
        {
            if(p->parent->left == node)
                p->parent->left = p;
            else
                p->parent->right = p;
        }
        p->left->parent = p;
        p->right->parent = p;
        if(p->left->right)
            p->left->right->parent = p->left;
        if(p->right->left)
            p->right->left->parent = p->right;

    }
}

void right_left_rotate(node_tp node)
{
    node_tp p;
    int itmp;
    if(node && node->right && node->right->left)
    {
                itmp = node->color;
                node->color = node->right->left->color;
                node->right->left->color = itmp;
        node->color = node->right->color;

        p = node->right->left;
        node->right->left = p->right;
        p->right = node->right;

        node->right = p->left;
        p->left = node;

        p->parent = node->parent;
        if(!p->parent)
            rb_tab_p = p;
        else
        {
            if(p->parent->left == node)
                p->parent->left = p;
            else
                p->parent->right = p;
        }
        p->left->parent = p;
        p->right->parent = p;
        if(p->left->right)
            p->left->right->parent = p->left;
        if(p->right->left)
            p->right->left->parent = p->right;

    }
}

int insert_rotate_type(node_tp node)
{
    if(node && node->parent->right == node && node->parent->parent->right ==node->parent)
        return -1;
    else if(node && node->parent->left == node && node->parent->parent->left ==node->parent)
        return 1;
    else if(node && node->parent->right == node && node->parent->parent->left ==node->parent)
        return -2;
    else if(node && node->parent->left == node && node->parent->parent->right ==node->parent)
        return 2;
    else
        return 0;

}


void rb_rotate(node_tp node, int type)
{
    switch(type)
    {
        case -1:
            left_rotate(node);
            break;
        case 1:
            right_rotate(node);
            break;
        case -2:
            left_right_rotate(node);
            break;
        case 2:
            right_left_rotate(node);
            break;
        default:
            break;
    }
}

void insert_rb_rotate(node_tp node)
{
    printf("\n11");
    rb_rotate(node->parent->parent, insert_rotate_type(node));
}

void insert_color_adjust(node_tp node)
{
    node_tp p;
    if(!node)
        return;    
    else if(!node->parent)
    {
        node->color = -1;
        return;
    }

    if(node->color == 1 && node->parent->color == 1)
        {
              p = node->parent->parent;
              if(p->left->color == p->right->color)
               {
                       p->left->color = p->right->color = -1;
                       p->color = 1;
                       node = p;
            insert_color_adjust(node);
               }
        else
                 insert_rb_rotate(node);

    }
}


int insert_node_s(node_tp node, int data)
{
    node_tp cur_p, p;
    cur_p = find_node(node, data);
    if(cur_p && cur_p->left && cur_p->right)
        return -1;

    if(!cur_p)
    {
        cur_p = (node_tp)malloc(sizeof(node_t));
        assert(cur_p != NULL);
        init_node(cur_p, data, -1);
        rb_tab_p = cur_p;
    }    

    p = (node_tp)malloc(sizeof(node_t));
    assert(p != NULL);
    init_node(p, 0,-1);
    cur_p->left = p;
    p->parent = cur_p;

    p = (node_tp)malloc(sizeof(node_t));
    assert(p != NULL);
    init_node(p, 0,-1);
    cur_p->right = p;
    p->parent = cur_p;
    
    cur_p->data = data;
    cur_p->color = 1;
        
    insert_color_adjust(cur_p);
    return 0;    
}

int insert_node(int data)
{
    return insert_node_s(rb_tab_p, data);
}


int del_rotate_type(node_tp black_p)
{
    node_tp parent_p, brother_p;
    if(black_p && black_p->parent)
    {
            parent_p = black_p->parent;
                if(parent_p->left == black_p)
                    brother_p = parent_p->right;
            else
                    brother_p = parent_p->left;
    
    if(brother_p->color == 1 && brother_p == parent_p->right)
                   return -1;
        else if(brother_p->color == 1 && brother_p == parent_p->left)
                return 1;
        else if(brother_p->color == -1 && brother_p == parent_p->right &&  brother_p->right->color == 1)
                return -1;
        else if(brother_p->color == -1 && brother_p == parent_p->left &&  brother_p->left->color == 1)
                return 1;
        else if(brother_p->color == -1 && brother_p == parent_p->right && brother_p->left->color == 1 && brother_p->right->color == -1)
                return 2;
        else if(brother_p->color == -1 && brother_p == parent_p->left && brother_p->left->color == -1 && brother_p->right->color == 1)
                return -2;
    }
    return 0;
}

void del_rb_rotate(node_tp node)
{
     rb_rotate(node->parent, del_rotate_type(node));
}


void del_color_adjust(node_tp black_p)
{
    node_tp parent_p, brother_p;
    if(!black_p)
        return;
    else if(black_p == rb_tab_p || black_p->color == 1)
    {
        black_p->color = -1;
        return;
    }
    parent_p = black_p->parent;
    if(parent_p->left == black_p)
        brother_p = parent_p->right;
    else
        brother_p = parent_p->left;

    if(brother_p->color == -1 && brother_p->left->color == -1 && brother_p->right->color == -1)
    {
        brother_p->color = 1;
        black_p = black_p->parent;
    }
    else if(brother_p->color == 1)
    {
        del_rb_rotate(black_p);
    }
    else
    {
        del_rb_rotate(black_p);
        black_p = NULL;
    }
    del_color_adjust(black_p);
            
}

int del_node_s(node_tp node, int data)
{
    node_tp pre_p, cur_p, black_p = NULL;
    cur_p = find_node(node, data);
    if(!cur_p || !cur_p->left || !cur_p->right)
        return -1;
    
    if(!cur_p->left->left)
    {
        if(cur_p->color == -1)
            black_p = cur_p->right;

        if(!cur_p->parent)
        {
            rb_tab_p = cur_p->right;
            rb_tab_p->parent = NULL;
        }
        else
        {
            if(cur_p->parent->left == cur_p)
                cur_p->parent->left = cur_p->right;
            else
                cur_p->parent->right = cur_p->right;
            cur_p->right->parent = cur_p->parent;
        }
        printf("\nfree data=%d", cur_p->data);
        free(cur_p->left);
        free(cur_p);
        if(!rb_tab_p->left || !rb_tab_p->right)
        {
            free(rb_tab_p);
            rb_tab_p = NULL;
            black_p = NULL;
        }
    }
    else
    {
        pre_p = max_node(cur_p->left);
        if(pre_p->color == -1)    
            black_p = pre_p->left;
        cur_p->data = pre_p->data;

        if(pre_p->parent->left == pre_p)
            pre_p->parent->left = pre_p->left;
        else
            pre_p->parent->right = pre_p->left;
        pre_p->left->parent = pre_p->parent;
    
        printf("\nfree data=%d", pre_p->data);
        free(pre_p->right);
        free(pre_p);
    }
    
    del_color_adjust(black_p);
    return 0;

}

int del_node(int data)
{
    return del_node_s(rb_tab_p, data);
}

void input_data(void)
{

    char str[20];
    int data;
    int ret;
    int i;
    for(i = 0; i < 255; i++)
        insert_node(i);
    
    
    while(1)
    {

/*        printf("\n\nenter data=");
        scanf("%s", str);
        if(strncmp(str, "ok", 2) == 0)
            break;
        ret = sscanf(str, "%d", &data);
        if(ret == 1)
        {
            travesal_mid();
            ret = insert_node(data);
            if(ret == 0)
                printf("\ninsert %d successful", data);
            travesal_mid();
        }

*/

                travesal_mid();
                printf("\n\ndel data=");
                scanf("%s", str);
                if(strncmp(str, "ok", 2) == 0)
                        break;
                ret = sscanf(str, "%d", &data);
                if(ret == 1)
                {
                        ret = del_node(data);
                        if(ret == 0)
                                printf("\ndel %d successful", data);
                        travesal_mid();
                }


        
    }
    free_tab();

}

int main(int argc, char **argv)
{

    input_data();


    return 0;
}
2008-07-27 10:41
快速回复:用C++实现红黑树
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016736 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved