之前讲的都是序列式容器,现在开始进入到关联式容器,关联式容器主要以Rb-tree和hash-table做为底层结构。

Rb-tree的节点设计

RB-tree结构和迭代器也是采用继承机制

节点结构

struct _Rb_tree_node_base
{typedef _Rb_tree_Color_type _Color_type;typedef _Rb_tree_node_base* _Base_ptr;// 节点值_Color_type _M_color;   _Base_ptr _M_parent;   _Base_ptr _M_left;_Base_ptr _M_right;// 最小元素就是最左边的元素static _Base_ptr _S_minimum(_Base_ptr __x){while (__x->_M_left != 0) __x = __x->_M_left;return __x;}// 最大元素就是最右边的元素static _Base_ptr _S_maximum(_Base_ptr __x){while (__x->_M_right != 0) __x = __x->_M_right;return __x;}
};// 数据和结构分离
template <class _Value>
struct _Rb_tree_node : public _Rb_tree_node_base
{typedef _Rb_tree_node<_Value>* _Link_type;_Value _M_value_field;
};

Rb-tree迭代器

基础迭代器

struct _Rb_tree_base_iterator
{typedef _Rb_tree_node_base::_Base_ptr _Base_ptr;typedef bidirectional_iterator_tag iterator_category;typedef ptrdiff_t difference_type;_Base_ptr _M_node;// 找下一个节点,用于实际迭代器的++void _M_increment(){// 如果有右子树,找右子树最左的元素if (_M_node->_M_right != 0) {   _M_node = _M_node->_M_right;while (_M_node->_M_left != 0)_M_node = _M_node->_M_left;}else {// 没有右子树,一直上溯找父节点,直到父节点不是右子节点_Base_ptr __y = _M_node->_M_parent;  while (_M_node == __y->_M_right) {_M_node = __y;__y = __y->_M_parent;} // 如果此时的右子节点不等于此时的父节点if (_M_node->_M_right != __y)_M_node = __y;}}// 找前一个元素,用于实际迭代器-- 操作void _M_decrement(){// 是红色节点,且父节点的父节点就是自己,也就是node就是header,因为root一定为黑// 结合下图if (_M_node->_M_color == _S_rb_tree_red &&_M_node->_M_parent->_M_parent == _M_node)_M_node = _M_node->_M_right;else if (_M_node->_M_left != 0) {  // 如果有左子节点_Base_ptr __y = _M_node->_M_left;while (__y->_M_right != 0)__y = __y->_M_right;_M_node = __y;}else {             // 不是根节点,也不是左子节点_Base_ptr __y = _M_node->_M_parent;  while (_M_node == __y->_M_left) {_M_node = __y;__y = __y->_M_parent;}_M_node = __y;}}
};

实际迭代器

template <class _Value, class _Ref, class _Ptr>
struct _Rb_tree_iterator : public _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, _Ref, _Ptr>                   _Self;typedef _Rb_tree_node<_Value>* _Link_type;  // 指向rb_node_Rb_tree_iterator() {}_Rb_tree_iterator(_Link_type __x) { _M_node = __x; }_Rb_tree_iterator(const iterator& __it) { _M_node = __it._M_node; }reference operator*() const { return _Link_type(_M_node)->_M_value_field; }
#ifndef __SGI_STL_NO_ARROW_OPERATORpointer operator->() const { return &(operator*()); }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */_Self& operator++() { _M_increment(); return *this; }_Self operator++(int) {_Self __tmp = *this;_M_increment();return __tmp;}_Self& operator--() { _M_decrement(); return *this; }_Self operator--(int) {_Self __tmp = *this;_M_decrement();return __tmp;}
};

Rb-tree的数据结构

和其他结构一样,首先是设置空间配置器和各种type,RB-tree有三个特殊的数据:

size_type node_count;   // 树节点大小

link_type header;    // 根节点前面再加一个节点,其颜色初始化为红色,以区分root

Compare key_compare;  // 节点间键值大小的比较准则,是个函数对象。

函数

void _M_empty_initialize() {_S_color(_M_header) = _S_rb_tree_red; // 令header为红色_M_root() = 0;_M_leftmost() = _M_header;    // 令header的左右子节点为自己_M_rightmost() = _M_header;}

元素插入分为两种:元素可重复(insert_equal)和元素不可重复(insert_unique)

元素平衡操作:考虑两个因素,旋转和颜色

元素的查找:根据key_compare寻找。

STL源码剖析(四):容器(6)Rb_tree相关推荐

  1. STL源码剖析(十三)关联式容器之rb_tree

    STL源码剖析(十三)关联式容器之rb_tree 文章目录 STL源码剖析(十三)关联式容器之rb_tree 一.rb_tree的数据结构 二.rb_tree的迭代器 三.rb_tree的操作 3.1 ...

  2. STL源码剖析 stack 栈 概述->(使用deque双端队列 / list链表)作为stack的底层容器

    Stack是一种先进后出的数据结构,他只有一个出口 stack允许 新增元素.移除元素.取得最顶端的元素,但是无法获得stack的内部数据,因此satck没有遍历行为 Stack定义的完整列表 (双端 ...

  3. STL源码剖析 map

    所有元素会根据元素的键值自动被排序 元素的类型是pair,同时拥有键值和实值:map不允许两个元素出现相同的键值 pair 代码 template <class T1,class T2> ...

  4. C++ STL源码剖析 笔记

    写在前面 记录一下<C++ STL源码剖析>中的要点. 一.STL六大组件 容器(container): 各种数据结构,用于存放数据: class template 类泛型: 如vecto ...

  5. STL(C++标准库,体系结构及其内核分析)(STL源码剖析)(更新完毕)

    文章目录 介绍 Level 0:使用C++标准库 0 STL六大部件 0.1 六大部件之间的关系 0.2 复杂度 0.3 容器是前闭后开(左闭右开)区间 1 容器的结构与分类 1.1 使用容器Arra ...

  6. STL源码剖析---红黑树原理详解下

    转载请标明出处,原文地址:http://blog.csdn.net/hackbuteer1/article/details/7760584       算法导论书上给出的红黑树的性质如下,跟STL源码 ...

  7. STL源码剖析 空间配置器 查漏补缺

    ptrdiff_t含义 减去两个指针的结果的带符号整数类型 ptrdiff_t (Type support) - C 中文开发手册 - 开发者手册 - 云+社区 - 腾讯云 std::set_new_ ...

  8. 《STL源码剖析》相关面试题总结

    一.STL简介 STL提供六大组件,彼此可以组合套用: 容器 容器就是各种数据结构,我就不多说,看看下面这张图回忆一下就好了,从实现角度看,STL容器是一种class template. 算法 各种常 ...

  9. 【STL源码剖析】迭代器

    [STL源码剖析]迭代器 第3章 迭代器(iterators)与traits编程技法(<STL源码剖析> ) 3.1 迭代器设计思维--STL关键所在 3.2 迭代器(iterator)是 ...

  10. 【《STL源码剖析》提炼总结】 第1节:空间配置器 allocator

    文章目录 一. 什么是空间配置器 二. STL allocator的四个操作: allocate,deallocate,construct,destroy `construct()` `destroy ...

最新文章

  1. wireshark和tcpdump抓包TCP乱序和重传怎么办?PCAP TCP排序工具分享
  2. 阿里云短信isp.RAM_PERMISSION_DENY没有访问权限解决办法
  3. 设计模式之迭代子模式
  4. 简单的SQL注入学习
  5. 三大运营商2月份运营数据发布:超过一半的中国人都在用移动
  6. javascript控制开始日期,和结束日期在同一个月
  7. Windows 编程[11] - WM_SIZE 消息
  8. 机器学习基础(二十七)—— 数据集的使用
  9. junit断言_JUnit断言
  10. matlab vl_feat,matlab 安装 vl_feat
  11. 嵌入式UWB定位测距设备开发实战(7)硬件之天线选型
  12. 程序员修炼之道(通俗版)——第八章
  13. 《黑客攻防从入门到精通》:社会工程学
  14. 颜色代码查询,在线颜色选择器,RGB颜色对照表
  15. #108 – The Logical Tree(逻辑树)
  16. 修改css样式后刷新网页无改变
  17. python列表前加星号是什么_Python中的星号:用途及使用方法(1)
  18. C++基础入门丨1. 初识C++像极了C语言
  19. Systrace 基础知识 - 锁竞争解读
  20. 苹果店里卖移动套餐,走出甲方思维

热门文章

  1. 本科,硕士们进了BAT拿高工资,为什么博士却要挤破头低薪进985高校?
  2. 一度智信电商:店铺转化率太低?
  3. 二项式(伯努利),多项式分布
  4. slack加错团队怎么退出_Slack团队聊天的最佳选择
  5. python爬虫:搜狗微信公众号文章信息的采集(https://weixin.sogou.com/),保存csv文件
  6. ORB-SLAM3中的词袋模型BoW
  7. 输入法规则(U模式输入)
  8. TLC2543和mini2440通信的速率
  9. 2018CSTC web2 writeup
  10. 5.2.6UART寄存器编程(下)