Linux+C的服务器之数据结构中的红黑树

文章介绍了红黑树的性质,包括其在保持平衡时的旋转操作,如左旋和右旋,以及红黑树的节点插入和删除策略。此外,还提及了在Linux服务器环境下配置samba、ssh和gcc的步骤,以及使用代码编辑器如vscode和sourceinsight进行编码。文章强调了理解和掌握红黑树时间复杂度的重要性,并提到红黑树在epoll事件管理中的应用。
摘要由CSDN通过智能技术生成

红黑树的性质

用来判断红黑树的性质

 红黑树的应用

 关于Linux服务器的环境配置

1.vm虚拟机安装一个Linux系统

2.在上一步的基础上再在系统安装samba+ssh+gcc编译器        

   smb用于远程访问共享文件夹;ssh用于xshell远程连接编写代码;

3.代码编辑器 vscode/sourceinsight

红黑树的结构体定义

红黑树子节点定义
//定义一个红黑树的模板文件
#define reboot_entry(name,type)         \  
        struct name{                    \
            unsigned char color;        \
            struct type rbtree_node *parent; \
            struct type rbtree_node *left;   \
            struct type rbtree_node *right;  \
        }

typedef int KEY_TYPE;  //用来定义key的任意类型

typedef struct _rbtree_node {

    KEY_TYPE key;
    void *value;
    // value

#if 1 //适合单个红黑树
    //rbtree
    unsigned char color;
    struct rbtree_node *parent;
    struct rbtree_node *left;
    struct rbtree_node *right;
#else  //可重复利用避免多次构建导致代码冗余
    reboot_entry( , _rbtree_node) node;
    //reboot_entry( , _rbtree_node) a;
    //reboot_entry( , _rbtree_node) b;
    //reboot_entry( , _rbtree_node) c;
#endif // 0

    // end

    //
} rbtree_node;
红黑树的根节点定义
typedef struct rbtree {
    rbtree_node *root;
    rbtree_node *nil; // NULL
} rbtree;

 红黑树的旋转

在红黑树的结构遭到破坏的时候我们会将其旋转旋转有俩中形势分为左旋和右旋为了树的平衡 左旋和右旋最多的旋转次数即它的高度

 左旋实现

结合上图: x的右指针 指向y的左指针  y的左指针 指向x    y的父节点指向 x的父节点  x的叶子节点指向y

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;
    //如果y的左指针是叶子节点就不需要更改
    if (y->left != T->nil) {
        y->left->parent = x;
    }

    // 2
    y->parent = x->parent;
    //判断x是否为空
    if (x->parent == T->nil) {//如果x的父节点是无 意味着x是根节点
        T->root = y;
    } else if (x == x->parent->left) {//如果x父节点有那就判断x是左叶子还是右叶子
        x->parent->left = y;
    } else {
        x->parent->right = y;
    }

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

}
右旋实现

结合上图: y的右指针 指向x的左指针  x的左指针 指向y    x的父节点指向 y的父节点  y的叶子节点指向x

// 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(rbtree *T, rbtree_node *z) {

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

    //遍历红黑树
    while (x != T->nil) {
    //y始终指向x的父节点
        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;

    // 

}

当插入的时候遇见节点值和插入值相等的时候 具体操作取决于具体业务 

当插入的子节点默认为红色的时候满足了红黑树性质的除4之外的条件这时候就需要去判断

 

 

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);

            }


        } 

    }

图三因为图二转换之后父,祖父节点颜色冲突且比较重(节点数量比较多)需要进行右旋转操作使得左右平衡      平衡的是黑高

红黑树的删除

对于开发中来说 只需要了解红黑树的时间复杂度 单独实现很少 最好可以自己实现一下红黑树

1.epoll的事件管理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值