STL源码分析之RB-tree关联容器 上

前言

本节将分析STL中难度很高的RB-tree, 如果对红黑树有所认识的那么分析起来的难度也就不是很大, 对红黑树没有太多了解的直接来分析的难度就非常的大了, 可以对红黑树有个了解红黑树之原理和算法详细介绍. 红黑树是很类似与AVL-tree的, 但是因为AVL-tree在插入,删除的操作做的实际操作很多, 综合而言计算机对内存的管理都采用平衡性相对AVL-tree较差一点的红黑树.

RB-tree规则:

  1. 每个节点的颜色是黑色或者红色
  2. 根节点必须是黑色的
  3. 每个叶节点(NULL)必须是黑色的
  4. 如果节点是红色的, 则子节点必须是黑色的
  5. 从节点到每个子孙节点的路径包括的黑色节点数目相同
// 红黑定义
typedef bool __rb_tree_color_type;
const __rb_tree_color_type __rb_tree_red = false;	
const __rb_tree_color_type __rb_tree_black = true;

本节就只分析RB-tree的基本结构, 但rb-tree的很多功能都是调用基本结构实现的功能, 像左旋, 右旋, 删除, 调整红黑树这些都非常的重要.

RB-tree基本结构分析

基本结构与list相似, 将节点与数据分开定义, __rb_tree_node_base定义指针; __rb_tree_node继承前者, 增加了数据, 就是一个完整的节点.

RB-tree基本结构

__rb_tree_node_base

struct __rb_tree_node_base
{
   
  typedef __rb_tree_color_type color_type;	
  typedef __rb_tree_node_base* base_ptr;	

  color_type color; 	// 定义节点颜色
  base_ptr parent;		// 定义父节点
  base_ptr left;		// 定义左孩子
  base_ptr right;		// 定义右孩子

    // 查找最小节点
  static base_ptr minimum(base_ptr x)
  {
   
    while (x->left != 0) x = x->left;
    return x;
  }

    // 查找最大节点
  static base_ptr maximum(base_ptr x)
  {
   
    while (x->right != 0) x = x->right;
    return x;
  }
};

__rb_tree_node : 完整的节点

template <class Value>
struct __rb_tree_node : public __rb_tree_node_base	// 继承__rb_tree_node_base
{
   
  typedef __rb_tree_node<Value>* link_type;
  Value value_field;	// 定义节点数据
};
RB-tree迭代器

__rb_tree_base_iterator 迭代器基本结构

迭代器中incrementdecrement函数是实现++与–的功能的核心.

struct __rb_tree_base_iterator
{
   
  typedef __rb_tree_node_base::base_ptr base_ptr;
  typedef bidirectional_iterator_tag iterator_category;	// bidirectional_iterator_tag类型的迭代器
  typedef ptrdiff_t difference_type;
  base_ptr node;	// 指针节点

    // ++核心函数
    // 节点是从node节点出发, 一直寻找右节点的左孩子, 每次找到比上次大的元素
  void increment()
  {
   
      // 有右节点, 就往右节点走
    if (node->right != 0) {
   
      node = node->right;
        // 一直往左节点走, 直到走到头
      while (node->left != 0)
        node = node->left;
    }
      // 没有右节点, 就寻找父节点
    else {
   
      base_ptr y = node->parent;
        // 如果该节点是父节点的右孩子就继续往上找, 直到y节点不是父节点的右孩子
      while (node == y->right) {
   
        node = y;
        y = y->parent;
      }
      if (node->right != y)
        node = y;
    }
  }
	
    // --核心代码
    // 节点是从node节点出发, 一直寻找左节点的右孩子, 每次找到比上次小的元素
  void decrement()
  {
   
      // 只有根节点, 每次--都是根节点
    if (node->color == __rb_tree_red && node->parent->parent == node)
      node = node->right;
      // 有左节点
    else if (node->left != 0) {
   
        // 往左节点走
      base_ptr y = node->left;
        // 只要有右节点就一直往右节点走
      while (y->right != 0)
        y = y->right;
      node = y;
    }
      // 没有左节点
    else {
   
        // 寻找父节点
      base_ptr y = node->parent;
        // 如果当前节点是父节点的左孩子就继续寻找父节点直到不再是左孩子
      while (node == y->left) {
   
        node = y;
        y = y->parent;
      }
      node = y;
    }
  }
};

__rb_tree_iterator 迭代器

template <class Value, class Ref, class Ptr>
struct __rb_tree_iterator : public __rb_tree_base_iterator	// 继承__rb_tree_base_iterator
{
   
  typedef Value value_type;
  typedef Ref reference;
  typedef Ptr pointer;
  typedef __rb_tree_iterator<Value, Value&, Value*>             iterator;
  typedef __rb_tree_iterator<Value, const Value&, const Value*> const_iterator;
  typedef __rb_tree_iterator<Value,
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值