首页 > 其他分享 >红黑树

红黑树

时间:2024-09-25 13:37:50浏览次数:1  
标签:node pp right rb 红黑树 red left

#include "common.h"

typedef struct rb_node_t rb_node_t;

struct rb_node_t
{
    rb_node_t *m_parent;
    rb_node_t *m_left;
    rb_node_t *m_right;
    bool m_red;
    int m_value;
};

rb_node_t *rb_node_new(rb_node_t *parent, int value)
{
    rb_node_t *p = (rb_node_t *)calloc(1, sizeof(rb_node_t));
    p->m_parent = parent;
    p->m_red = true;
    p->m_value = value;
    return p;
}

void rotate_left(rb_node_t **root, rb_node_t *p)
{
    rb_node_t *pp = p->m_parent;
    rb_node_t *r = p->m_right;

    p->m_right = r->m_left;
    r->m_left = p;
    if (pp == NULL)
    {
        *root = r;
    }
    else if (p == pp->m_left)
    {
        pp->m_left = r;
    }
    else
    {
        pp->m_right = r;
    }

    if (p->m_right)
    {
        p->m_right->m_parent = p;
    }
    p->m_parent = r;
    r->m_parent = pp;
}

void rotate_right(rb_node_t **root, rb_node_t *p)
{
    rb_node_t *pp = p->m_parent;
    rb_node_t *l = p->m_left;

    p->m_left = l->m_right;
    l->m_right = p;
    if (pp == NULL)
    {
        *root = l;
    }
    else if (p == pp->m_left)
    {
        pp->m_left = l;
    }
    else
    {
        pp->m_right = l;
    }

    if (p->m_left)
    {
        p->m_left->m_parent = p;
    }
    p->m_parent = l;
    l->m_parent = pp;
}

void fix_insert(rb_node_t **root, rb_node_t *p)
{
    while (p->m_red)
    {
        rb_node_t *pp = p->m_parent;
        rb_node_t *b = (p == pp->m_left ? pp->m_right : pp->m_left);

        if (b && b->m_red)
        {
            p->m_red = false;
            b->m_red = false;

            if (pp->m_parent)
            {
                pp->m_red = true;
                p = pp->m_parent;
                continue;
            }
        }
        else if (p == pp->m_left)
        {
            if (p->m_right && p->m_right->m_red)
            {
                rotate_left(root, p);
                p = p->m_parent;
            }

            p->m_red = false;
            pp->m_red = true;
            rotate_right(root, pp);
        }
        else
        {
            if (p->m_left && p->m_left->m_red)
            {
                rotate_right(root, p);
                p = p->m_parent;
            }

            p->m_red = false;
            pp->m_red = true;
            rotate_left(root, pp);
        }

        break;
    }
}

void fix_remove(rb_node_t **root, rb_node_t *p)
{
    while (p->m_parent && p->m_red == false)
    {
        rb_node_t *pp = p->m_parent;
        if (p == pp->m_left)
        {
            rb_node_t *b = pp->m_right;
            if (b->m_red)
            {
                pp->m_red = true;
                b->m_red = false;
                rotate_left(root, pp);
                b = pp->m_right;
            }

            if (b->m_left && b->m_left->m_red || b->m_right && b->m_right->m_red)
            {
                if (b->m_right == NULL || b->m_right->m_red == false)
                {
                    b->m_left->m_red = false;
                    b->m_red = true;
                    rotate_right(root, b);
                    b = pp->m_right;
                }

                b->m_red = pp->m_red;
                b->m_right->m_red = false;
                pp->m_red = false;
                rotate_left(root, pp);
            }
            else
            {
                b->m_red = true;
                p = pp;
                continue;
            }
        }
        else
        {
            rb_node_t *b = pp->m_left;
            if (b->m_red)
            {
                pp->m_red = true;
                b->m_red = false;
                rotate_right(root, pp);
                b = pp->m_left;
            }

            if (b->m_left && b->m_left->m_red || b->m_right && b->m_right->m_red)
            {
                if (b->m_left == NULL || b->m_left->m_red == false)
                {
                    b->m_right->m_red = false;
                    b->m_red = true;
                    rotate_left(root, b);
                    b = pp->m_left;
                }

                b->m_red = pp->m_red;
                b->m_left->m_red = false;
                pp->m_red = false;
                rotate_right(root, pp);
            }
            else
            {
                b->m_red = true;
                p = pp;
                continue;
            }
        }
        break;
    }
    p->m_red = false;
}

void rb_insert(rb_node_t **root, int value)
{
    rb_node_t *c = *root;
    rb_node_t *p = NULL;
    while (c)
    {
        p = c;
        c = (value <= c->m_value) ? c->m_left : c->m_right;
    }

    if (p == NULL)
    {
        *root = rb_node_new(NULL, value);
        (*root)->m_red = false;
        return;
    }

    if (value <= p->m_value)
    {
        p->m_left = rb_node_new(p, value);
    }
    else
    {
        p->m_right = rb_node_new(p, value);
    }
    fix_insert(root, p);
}

void rb_remove(rb_node_t **root, int value)
{
    rb_node_t *p = *root;
    while (p && p->m_value != value)
    {
        p = (value < p->m_value) ? p->m_left : p->m_right;
    }
    if (p == NULL)
    {
        return;
    }
    if (p->m_left && p->m_right)
    {
        rb_node_t *c = p->m_right;
        while (c->m_left)
        {
            c = c->m_left;
        }
        p->m_value = c->m_value;
        p = c;
    }

    rb_node_t *pp = p->m_parent;
    rb_node_t *r = (p->m_left ? p->m_left : p->m_right);
    if (r)
    {
        r->m_parent = pp;
        r->m_red = false;
        if (pp == NULL)
        {
            *root = r;
        }
        else if (p == pp->m_left)
        {
            pp->m_left = r;
        }
        else
        {
            pp->m_right = r;
        }
    }
    else if (pp == NULL)
    {
        *root = NULL;
    }
    else
    {
        fix_remove(root, p);
        if (p == pp->m_left)
        {
            pp->m_left = NULL;
        }
        else
        {
            pp->m_right = NULL;
        }
    }

    free(p);
}

int rb_depth(rb_node_t *p)
{
    if (p == NULL)
    {
        return 0;
    }
    int a = rb_depth(p->m_left);
    int b = rb_depth(p->m_right);
    return 1 + (a < b ? b : a);
}

int main()
{
    rb_node_t *root = NULL;

    for (int i = 0; i < 1024 * 1024; i++)
    {
        rb_insert(&root, i);
    }
    printf("rb_depth = %d\n", rb_depth(root));

    for (int i = 0; i < 1024 * 1024 - 1024; i++)
    {
        rb_remove(&root, i);
    }
    printf("rb_depth = %d\n", rb_depth(root));

    for (int i = 0; i < 1024 * 1024 - 1024; i++)
    {
        rb_insert(&root, i);
    }
    printf("rb_depth = %d\n", rb_depth(root));

    for (int i = 0; i < 1024 * 1024 - 1024; i++)
    {
        rb_remove(&root, i);
    }
    printf("rb_depth = %d\n", rb_depth(root));
}

 

标签:node,pp,right,rb,红黑树,red,left
From: https://www.cnblogs.com/kehuadong/p/18431150

相关文章

  • 《 C++ 修炼全景指南:十二 》用红黑树加速你的代码!C++ Set 和 Map 容器从入门到精通
    摘要本文详细介绍了基于红黑树实现的Set和Map容器,包括其底层设计原理、插入和删除操作的实现细节、性能分析与优化策略,以及实际应用场景和未来发展方向。通过采用红黑树的数据结构,Set和Map容器能够高效地处理有序数据,保持O(logn)的时间复杂度,适用于各种数据存储......
  • Java集合类面试题:Map接口(链表、HashMap、红黑树)
    收集大量Java经典面试题目......
  • C++: 使用红黑树模拟实现STL中的map和set
    目录1.红黑树的迭代器++和--2.改造红黑树3.set的模拟实现4.map的模拟实现5.RBTree的改造代码博客主页:酷酷学正文开始1.红黑树的迭代器迭代器的好处是可以方便遍历,是数据结构的底层实现与用户透明打开C++的源码我们可以发现,其实源码中的底层大概如下......
  • c++修炼之路之AVL树与红黑树
    目录一:AVL树1.AVL树的概念2.AVL树插入数据后平衡因子及更新的情况3.AVL树节点的定义 4.AVL树的插入及旋转 二:红黑树 1.红黑树的概念及性质2.红黑树节点的定义3.红黑树的插入操作情况 4.红黑树与AVL树的比较 接下来的日子会顺顺利利,万事胜意,生活明朗---------......
  • TreeMap源码详解—彻底搞懂红黑树的平衡操作
    介绍TreeSet和TreeMap在Java里有着相同的实现,前者仅仅是对后者做了一层包装,也就是说TreeSet里面有一个TreeMap(适配器模式)。JavaTreeMap实现了SortedMap接口,也就是说会按照key的大小顺序对Map中的元素进行排序,key大小的评判可以通过其本身的自然顺序(naturalordering),也可以通......
  • TreeMap源码详解—彻底搞懂红黑树的平衡操作
    介绍TreeSet和TreeMap在Java里有着相同的实现,前者仅仅是对后者做了一层包装,也就是说TreeSet里面有一个TreeMap(适配器模式)。JavaTreeMap实现了SortedMap接口,也就是说会按照key的大小顺序对Map中的元素进行排序,key大小的评判可以通过其本身的自然顺序(naturalordering),也可以......
  • 红黑树的实现
    上一篇中我们讲述了红黑树的插入,以及删除时需要进行的各种调整的情况,根据这些情况,我们可以用代码实现红黑树的插入与删除操作.节点的定义一颗红黑树的定义如下://定义颜色枚举类型enumColor{RED,BLACK};template<classT>structRed_Black_Node{Red_Bla......
  • C++笔记19•数据结构:红黑树(RBTree)•
    红黑树1.简介:    红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。当搜索二叉树退化为单支树时,搜......
  • Go红黑树
    packagemainimport"fmt"constRED=0constBLACK=1typeTypeinttypeRBNodestruct{coloruint8keyTypeleft,right,parent*RBNode}typeRBRootstruct{node*RBNode}funcrb_is_red(node*RBNode)bool{r......
  • 红黑树
    红黑树的概念:红黑树是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。红黑树的性质:每个结点不是红色就是黑色根......