红黑树插入的栈实现

可以不使用parent 指针,直接使用栈实现,方法是在插入时记下插入结点的所有祖先结点,然后回溯时再使用,以下代码使用数组简单实现栈结构。

/* ================================================================== */
/* no parent rbtree */
/* ================================================================== */
void __rb_np_rotate_left(struct rb_node *node, struct rb_node *parent, struct rb_root *root)
{
    struct rb_node *right = node->right;

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

    if (parent == NULL) {
        root->rb_node = right;
    }
    else {
        if (parent->left == node)
            parent->left = right;
        else
            parent->right = right;
    }
}

void __rb_np_rotate_right(struct rb_node *node, struct rb_node *parent, struct rb_root *root)
{
    struct rb_node *left = node->left;

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

    if (parent == NULL) {
        root->rb_node = left;
    }
    else {
        if (parent->left == node)
            parent->left = left;
        else
            parent->right = left;
    }
}


/* use s[0] as NULL pointer */
#define PUSH_S(s, n, i) (s)[++(i)]=(n)
#define POP_S(s, i)     (s)[(i)--]
#define TOP_S(s, i)     (s)[(i)]

static void rb_np_insert_color(struct rb_node *node, struct rb_root *root, struct rb_node **s, int i)
{
    struct rb_node *parent, *uncle, *gparent, *tmp;

    for (;;) {
        parent = POP_S(s, i);
        if (parent == NULL || parent->color == RB_BLACK) {
            break;
        }
        gparent = POP_S(s, i);
        
        if (parent == gparent->left) {
            uncle = gparent->right;
            if (uncle && uncle->color == RB_RED) { /* case 1 */
                parent->color = RB_BLACK;
                uncle->color = RB_BLACK;
                gparent->color = RB_RED;
                node = gparent;
                continue;
            }

            if (parent->right == node) { /* case 2 */
                __rb_np_rotate_left(parent, gparent, root);
                tmp = node;
                node = parent;
                parent = tmp;
            }

            /* case 3 */
            tmp = TOP_S(s, i);
            __rb_np_rotate_right(gparent, tmp, root);
            parent->color = RB_BLACK;
            gparent->color = RB_RED;
            break;
        }
        else {
            uncle = gparent->left;
            if (uncle && uncle->color == RB_RED) { /* case 1 */
                parent->color = RB_BLACK;
                uncle->color = RB_BLACK;
                gparent->color = RB_RED;
                node = gparent;
                continue;
            }

            if (parent->left == node) { /* case 2 */
                __rb_np_rotate_right(parent, gparent, root);
                tmp = node;
                node = parent;
                parent = tmp;
            }

            /* case 3 */
            tmp = TOP_S(s, i);
            __rb_np_rotate_left(gparent, tmp, root);
            parent->color = RB_BLACK;
            gparent->color = RB_RED;
            break;
        }
    }
    root->rb_node->color = RB_BLACK;
}
    
void rb_np_insert(struct rb_node *node, struct rb_root *root)
{
    int i = 0;
    struct rb_node *p = root->rb_node, *parent = NULL;
    struct rb_node *s[1024] = {0, };

    while (p) {
        PUSH_S(s, p, i);
        if (node->key < p->key)
            p = p->left;
        else
            p = p->right;
    }

    node->left = node->right = NULL;
    
    parent = TOP_S(s, i);
    if (parent == NULL) {
        node->color = RB_BLACK;
        root->rb_node = node;
    }
    else {
        node->color = RB_RED;
        if (node->key < parent->key)
            parent->left = node;
        else 
            parent->right = node;

        if (parent->color == RB_RED)
            rb_np_insert_color(node, root, s, i);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值