第一天:红黑树的学习

本文章为个人学习笔记,仅供参考(文末有代码)

1.什么是红黑树?
****红黑树是一种自平衡的二叉查找树,是一个高效查找的数据结构。

2.红黑树的特征都有哪些?
****1. 每一个结点都有一个颜色,要么为红色,要么为黑色;
****2. 树的根结点为黑色;
****3. 树中不存在两个相邻的红色结点(即红色结点的父结点和孩子结点均不能 是红色)
****4. 从任意一个结点(包括根结点)到其任何后代 NULL 结点(默认是黑色的)的每条路径都具有相同数量的黑色结点。

3.红黑树的左旋与右旋(叶子节点已隐藏)
在这里插入图片描述
4.红黑树的插入!
****前提条件:
1.在我们每插入一个点之前,原本的红黑树就已经达到平衡条件。
2.一般为了不破坏红黑树的平衡条件,我们把插入的节点赋为红色。进而再通过旋转方式使之达到平衡。

主要是第三点和第四点:
父子节点不能都是红颜色
每个节点对应的黑高相同(需要考虑父亲,祖父,叔父节点)

父节点红,叔父节点红---------------父,叔父变黑,祖父变红

在这里插入图片描述


父节点红,叔父节点黑

****1.当前节点为右子树---------------当前节点左旋(父节点左旋一样的)
在这里插入图片描述


***2.当前节点为左子树---------------父节点右旋,父节点变黑,祖父节点变红
在这里插入图片描述


以上为三种转换情况,如果转换后祖父节点和其祖父的父节点都为红色,则循环直至平衡为止

5.红黑树的删除

不考虑颜色的时候是这样的

***1.没有子树--------
在这里插入图片描述


***2.只有左子树或者右子树--------
在这里插入图片描述


3.有左子树或者右子树在这里插入图片描述


红黑树的删除

当前结点是父结点的左子树的情况
1.当前结点的兄弟结点是红色的
2.当前结点的兄弟结点是黑色的,而且兄弟结点的两个孩子结点都是黑色的
3.当前结点的兄弟结点是黑色的,而且兄弟结点的左孩子是红色的,右孩子是黑色的
4.当前结点的兄弟结点是黑色的,而且兄弟结点的右孩子是红色的

对应1.操作(删除786):小弟节点右旋,兄弟节点变黑,祖父节点变红

在这里插入图片描述


对应2.操作(删除62):兄弟节点变红,父节点的兄弟节点变红,父亲节点的兄弟节点变红

在这里插入图片描述


对应操作:

在这里插入图片描述


在这里插入图片描述

#define RED     0
#define BLACK   1

typedef int KEY_TYPE;

typedef struct _rbtree_node {
    //rbtree
    unsigned char color;
    struct rbtree_node *parent;
    struct rbtree_node *left;
    struct rbtree_node *right;
    // end


    KEY_TYPE key; 

    // value
    //
} rbtree_node;


struct rbtree {
    rbtree_node *root;
    rbtree_node *nil; // NULL
};

// rotate 

void rbtree_left_rotate(rbtree *T, rbtree_node *x) {
    // NULL --> T->nil
    if (x == T->nil) return ;
    // 1
    rbtree_node *y = x->right;

    x->right = y->left;
    if (y->left != T->nil) {
        y->left->parent = x;
    }

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

    // 3
    y->left = x;
    x->parent = y;

}

// x --> y, y -->x 
// left --> right, right --> left

void rbtree_right_rotate(rbtree *T, rbtree_node *y) {
    // NULL --> T->nil
    if (y == T->nil) return ;
    // 1
    rbtree_node *x = y->left;

    y->left = x->right;
    if (y->left != T->nil) {
        y->left->parent = x;
    }

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

    // 3
    y->left = x;
    x->parent = y;

}


void rbtree_insert_fixup(rbtree *T, rbtree_node *z) {
    //
    // z->color == RED
    // z->parent->color == RED

    // z--> RED
    while (z->parent->color == RED) { // 

        if (z->parent == z->parent->parent->left) {

            y = z->parent->parent->right; //

            if (y->color == RED) {

                z->parent->color = BLACK;
                z->parent->parent->color = RED;
                y->color = BLACK;

                z = z->parent->parent; //
            } else { // 

                if (z = z->parent->right) {
                    z = z->parent;
                    rbtree_left_rotate(T, z);
                }

                z->parent->color = BLACK;
                z->parent->parent->color = RED;
                rbtree_right_rotate(T, z->parent->parent);

            }


        } 

    }


}

void rbtree_insert(rbtree *T, rbtree_node *z) {

    rbtree_node *y = T->nil;
    rbtree_node *x = T->root;

    while (x != T->nil) {

        y = x;

        if (z->key < x->key) {
            x = x->left;
        } else if (z->key > x->key) {
            x = x->right;
        } else { //Exist

        }

    }

    z->parent = y;
    if (y == T->nil) {
        T->root = z;
    } else if (z->key < y->key) {
        y->left = z;
    } else {
        y->right = z;
    }

    // z --> 
    z->color = RED;
    z->left = T->nil;
    z->right = T->nil;

    // 

}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值