6.Nginx红黑树rbtree

Nginx的定时器管理借助红黑树来完成,红黑树这种数据结构在很多开源项目中被广泛使用。


红黑树是一种自平衡二叉搜索树,可以在O(log n)时间内做查找、插入和删除,这里n是树中元素的数目。

红黑树是每个节点都带有颜色属性的二叉搜索数,颜色为红色或黑色。在二叉搜索树的一般要求以外,它还有以下的额外要求:

(1)节点是红色或黑色

(2)根节点是黑色的

(3)所有叶子都是黑色(叶子是NIL节点)

(4)每个红色节点必须有两个黑色的子节点

(5)从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点


/*core/ngx_rbtree.h */
typedef struct ngx_rbtree_s  ngx_rbtree_t;

// rbtree节点结构体
struct ngx_rbtree_s {
   ngx_int_t       key;     //节点值
   ngx_rbtree_t   *left;    //左子节点
   ngx_rbtree_t   *right;   //右子节点
   ngx_rbtree_t   *parent;  //父节点
   char            color;   //颜色
};

/*
    rbtree获取值最小的节点
    param node: 根节点指针的指针
      sentinel: 作为哨兵的NIL节点指针
*/
ngx_inline static ngx_rbtree_t *ngx_rbtree_min(ngx_rbtree_t *node,
                                               ngx_rbtree_t *sentinel)
{
   // 二叉搜索数: 节点的左子树的值都比其小
   // 那么只需要找到最左侧的节点即为最小节点
   while (node->left != sentinel) {
       node = node->left;
   }

   return node;
}


/*core/ngx_rbtree.c */

/*
    rbtree左旋调整
    param root: 根节点指针的指针
      sentinel: 作为哨兵的NIL节点指针
          node: 作为旋转基点的节点指针
*/
ngx_inline void ngx_rbtree_left_rotate(ngx_rbtree_t **root,
                                       ngx_rbtree_t *sentinel,
                                       ngx_rbtree_t *node)
{
    ngx_rbtree_t  *temp;

    temp = node->right;                      // temp指向node的右子节点
    node->right = temp->left;                // 让node的右子节点的左孩子成为node的右孩子

    if (temp->left != sentinel) {            // 如果node的原右子节点的左孩子不为空,
        temp->left->parent = node;           // 那么修改其父亲为node
    }

    temp->parent = node->parent;             // 修改node的原右子节点的父亲为node的父亲

    if (node == *root) {                     // 如果node为根节点,
        *root = temp;                        // 那么新的根节点为node的原右子节点

    } else if (node == node->parent->left) { // 如果node是其父亲的左孩子,
        node->parent->left = temp;           // 那么修改node的父亲的左孩子为node的原右子节点

    } else {                                 // 如果node是其父亲的右孩子,
        node->parent->right = temp;          // 那么修改node的父亲的右孩子为node的原右子节点
    }

    temp->left = node;                       // 修改node的原右子节点的左孩子为node
    node->parent = temp;                     // 修改node的父亲为其原右子节点
}


/*
    rbtree右旋调整
    param root: 根节点指针的指针
      sentinel: 作为哨兵的NIL节点指针
          node: 作为旋转基点的节点指针
*/
ngx_inline void ngx_rbtree_right_rotate(ngx_rbtree_t **root,
                                        ngx_rbtree_t *sentinel,
                                        ngx_
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值