map内存结构
来源:互联网 发布:上瘾网络剧未删减资源 编辑:程序博客网 时间:2024/05/16 09:49
GNU实现的std::map的数据结构模型是红黑树。红黑树是平衡二叉树的一类变种。可以保证在最坏情况下花费O(logN)时间。
其着色性质有如下特性:
1,根节点是黑色的
2,每个节点要么是红色,要么是黑色
3,如果一个节点是红色,其子节点必须是黑色。
4,从一个节点到一个NULL指针的每一条路径必须包含相同数目的黑色节点
由上面的几条特性可以推论出,查找是一个对数操作。
我写了一个简单的例子
#include <string>
#include <map>
int main(int argc, char * argv[])
{
typedef std::pair<int, std::string> cpair;
std::map<int, std::string> map;
map.insert(cpair(3, "c"));
map.insert(cpair(1, "a"));
map.insert(cpair(4, "d"));
map.erase(3);
return 0;
}
使用gbd在map.insert(cpair(3, "c"))后加了断点
可以看到,map的实现在_M_t中
map = {_M_t = {
_M_impl = {<std::allocator<std::_Rb_tree_node<std::pair<int const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >> = {<__gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<int const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >> = {<No data fields>}, <No data fields>}, _M_key_compare = {<std::binary_function<int, int, bool>> = {<No data fields>}, <No data fields>}, _M_header = {_M_color = std::_S_red, _M_parent = 0x80f2010, _M_left = 0x80f2010, _M_right = 0x80f2010}, _M_node_count = 1}}}
可以看到在map内存的尾部保存了红黑树的着色信息和左右子树。
在map.insert(cpair(1, "a"));后继续加断点
map = {_M_t = {
_M_impl = {<std::allocator<std::_Rb_tree_node<std::pair<int const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >> = {<__gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<int const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >> = {<No data fields>}, <No data fields>}, _M_key_compare = {<std::binary_function<int, int, bool>> = {<No data fields>}, <No data fields>}, _M_header = {
_M_color = std::_S_red, _M_parent = 0x80f2010, _M_left = 0x80f2048, _M_right = 0x80f2010}, _M_node_count = 2}}}
由于key值1比3小,所以按照平衡树的规则,插入在左节点上
继续在map.insert(cpair(4, "d"));后加断点
map = {_M_t = {
_M_impl = {<std::allocator<std::_Rb_tree_node<std::pair<int const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >> = {<__gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<int const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >> = {<No data fields>}, <No data fields>}, _M_key_compare = {<std::binary_function<int, int, bool>> = {<No data fields>}, <No data fields>}, _M_header = {
_M_color = std::_S_red, _M_parent = 0x80f2010, _M_left = 0x80f2048, _M_right = 0x80f2080}, _M_node_count = 3}}}
可以看到map的右子树变化了,由于key值4比3大,所以插入到右节点上。
同时可以看到_M_node_count的节点信息随着插入而增长
在erase后加断点
map = {_M_t = {
_M_impl = {<std::allocator<std::_Rb_tree_node<std::pair<int const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >> = {<__gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<int const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >> = {<No data fields>}, <No data fields>}, _M_key_compare = {<std::binary_function<int, int, bool>> = {<No data fields>}, <No data fields>}, _M_header = {
_M_color = std::_S_red, _M_parent = 0x80f2080, _M_left = 0x80f2048, _M_right = 0x80f2080}, _M_node_count = 2}}}
_M_node_count 节点总数少一个,而红黑树进行一次单旋转,改变了父节点的值。有此我们可知
由于每次插入和删除过程,红黑树要进行旋转以保证符合上述的4条原则。所以使用在删除或者插入后,迭代器指向的内容不确定,所以不要在删除或者插入后使用迭代器。
而且map标准库的实现是非线程安全的,使用的时候注意多线程问题
- map内存结构
- c++的map,set内存结构
- 黑马程序员--07.集合框架--10.【Map.Entry内存结构】【Map集合的迭代方式】
- 内存结构
- 内存结构
- 内存结构
- 内存结构
- 内存结构
- 内存结构
- 内存结构
- 内存结构
- 内存结构
- 内存结构
- 内存结构
- 内存结构
- 内存结构
- Bit Map 位图结构
- map+结构体
- form属性method=”get/post”的两种方式对比
- 用java实现一个简单的网络爬虫
- 顺时针打印矩阵
- 1--java字符串学习
- jQuery - AJAX get() 和 post() 方法
- map内存结构
- Android Studio更改快捷键,让开发更快捷
- ubuntu系统安装的一些问题
- string显示问题
- 第一章 所有
- TCP三次握手,四次挥手过程
- 《Unity Shader 与 计算机图形学》第一章
- 神奇的动态规划---核电站(openjudge)
- C#中的值类型和引用类型