STL源码剖析(四):容器(6)Rb_tree
之前讲的都是序列式容器,现在开始进入到关联式容器,关联式容器主要以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相关推荐
- STL源码剖析(十三)关联式容器之rb_tree
STL源码剖析(十三)关联式容器之rb_tree 文章目录 STL源码剖析(十三)关联式容器之rb_tree 一.rb_tree的数据结构 二.rb_tree的迭代器 三.rb_tree的操作 3.1 ...
- STL源码剖析 stack 栈 概述->(使用deque双端队列 / list链表)作为stack的底层容器
Stack是一种先进后出的数据结构,他只有一个出口 stack允许 新增元素.移除元素.取得最顶端的元素,但是无法获得stack的内部数据,因此satck没有遍历行为 Stack定义的完整列表 (双端 ...
- STL源码剖析 map
所有元素会根据元素的键值自动被排序 元素的类型是pair,同时拥有键值和实值:map不允许两个元素出现相同的键值 pair 代码 template <class T1,class T2> ...
- C++ STL源码剖析 笔记
写在前面 记录一下<C++ STL源码剖析>中的要点. 一.STL六大组件 容器(container): 各种数据结构,用于存放数据: class template 类泛型: 如vecto ...
- STL(C++标准库,体系结构及其内核分析)(STL源码剖析)(更新完毕)
文章目录 介绍 Level 0:使用C++标准库 0 STL六大部件 0.1 六大部件之间的关系 0.2 复杂度 0.3 容器是前闭后开(左闭右开)区间 1 容器的结构与分类 1.1 使用容器Arra ...
- STL源码剖析---红黑树原理详解下
转载请标明出处,原文地址:http://blog.csdn.net/hackbuteer1/article/details/7760584 算法导论书上给出的红黑树的性质如下,跟STL源码 ...
- STL源码剖析 空间配置器 查漏补缺
ptrdiff_t含义 减去两个指针的结果的带符号整数类型 ptrdiff_t (Type support) - C 中文开发手册 - 开发者手册 - 云+社区 - 腾讯云 std::set_new_ ...
- 《STL源码剖析》相关面试题总结
一.STL简介 STL提供六大组件,彼此可以组合套用: 容器 容器就是各种数据结构,我就不多说,看看下面这张图回忆一下就好了,从实现角度看,STL容器是一种class template. 算法 各种常 ...
- 【STL源码剖析】迭代器
[STL源码剖析]迭代器 第3章 迭代器(iterators)与traits编程技法(<STL源码剖析> ) 3.1 迭代器设计思维--STL关键所在 3.2 迭代器(iterator)是 ...
- 【《STL源码剖析》提炼总结】 第1节:空间配置器 allocator
文章目录 一. 什么是空间配置器 二. STL allocator的四个操作: allocate,deallocate,construct,destroy `construct()` `destroy ...
最新文章
- wireshark和tcpdump抓包TCP乱序和重传怎么办?PCAP TCP排序工具分享
- 阿里云短信isp.RAM_PERMISSION_DENY没有访问权限解决办法
- 设计模式之迭代子模式
- 简单的SQL注入学习
- 三大运营商2月份运营数据发布:超过一半的中国人都在用移动
- javascript控制开始日期,和结束日期在同一个月
- Windows 编程[11] - WM_SIZE 消息
- 机器学习基础(二十七)—— 数据集的使用
- junit断言_JUnit断言
- matlab vl_feat,matlab 安装 vl_feat
- 嵌入式UWB定位测距设备开发实战(7)硬件之天线选型
- 程序员修炼之道(通俗版)——第八章
- 《黑客攻防从入门到精通》:社会工程学
- 颜色代码查询,在线颜色选择器,RGB颜色对照表
- #108 – The Logical Tree(逻辑树)
- 修改css样式后刷新网页无改变
- python列表前加星号是什么_Python中的星号:用途及使用方法(1)
- C++基础入门丨1. 初识C++像极了C语言
- Systrace 基础知识 - 锁竞争解读
- 苹果店里卖移动套餐,走出甲方思维
热门文章
- 本科,硕士们进了BAT拿高工资,为什么博士却要挤破头低薪进985高校?
- 一度智信电商:店铺转化率太低?
- 二项式(伯努利),多项式分布
- slack加错团队怎么退出_Slack团队聊天的最佳选择
- python爬虫:搜狗微信公众号文章信息的采集(https://weixin.sogou.com/),保存csv文件
- ORB-SLAM3中的词袋模型BoW
- 输入法规则(U模式输入)
- TLC2543和mini2440通信的速率
- 2018CSTC web2 writeup
- 5.2.6UART寄存器编程(下)