STL—set和map使用及源码剖析
Posted _Karry
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STL—set和map使用及源码剖析相关的知识,希望对你有一定的参考价值。
文章目录
容器rb_tree
容器rb_tree
封装了红黑树,是有序容器,提供了迭代器iterator
用以遍历,但不应使用iterator
直接改变元素值(虽然编程层面并没有禁止这样做)
rb_tree
提供两种插入操作:insert_unique
和insert_equal
前者表示节点的key
一定在整棵树中独一无二,否则插入失败;
后者表示节点的key
可重复
对于rb_tree
,定义一个概念:节点的value
包括其key
和data
,这里的data
表示一般说法中的value
template<class Key, // 指定key类型
class Value, // 指定Value类型
class KeyOfValue, // 仿函数类,指定从Value中获取Key的方式
class Compare, // 仿函数类,指定Key的排序方式
class Alloc = alloc>
class rb_tree
protected:
typedef __rb_tree_node <Value> rb_tree_node;
public:
typedef rb_tree_node *link_type;
protected:
size_type node_count; // rb_tree的大小(节点数量)
link_type header; // 头节点
Compare key_compare; // Key的排序方式
;
rb_tree
的header
指向一个多余的空节点,用以维持其前闭后开的特性
rb_tree
的使用:
rb_tree<int, int, identity<int>, less<int>> itree;
cout << itree.empty() << endl; // 1
cout << itree.size() << endl; // 0
itree.insert_unique(3);
itree.insert_unique(8);
itree.insert_unique(5);
itree.insert_unique(9);
itree.insert_unique(13);
itree.insert_unique(5); //no effect, since using insert_unique()
cout << itree.empty() << endl; //0
cout << itree.size() << endl; //5
cout << itree.count(5) << endl; //1
itree.insert_equal(5);
itree.insert_equal(5);
cout << itree.size() << endl; //7, since using insert_equal()
cout << itree.count(5) << endl; //3
容器set和multiset
概述
set
和multiset
底层是用红黑树来实现的
set
和multiset
的key和value是一致的
通过set
的迭代器不能改变set
里面的元素键值.因为改变了键值,红黑树的结点就得重新排列了,就会破坏set
的组织.所以set
的迭代器被定义为红黑树底层的const_iterator
,杜绝写入操作
set
元素的key
必須独一无二,因此其insert()
调用的是内部rb_tree
的insert_unique()
方法;
multiset
元素的key
可以重复,因此其insert()
调用的是内部rb_tree
的insert_equal()
方法
使用
#include <set>
#include <algorithm>
#include <iostream>
using namespace std;
void main()
//初始化
set<int> s; //默认构造
set<int> s1(s); //拷贝构造
set<int> s2 = s; //重载等号操作符
//遍历
for (auto i : s)
cout << i << endl;
for (auto i = s.begin(); i != s.end(); i++)
cout << *i << endl;
//成员函数
s.insert(5); //插入数据只能有insert这一个方法
s.size(); //返回容器中元素个数
s.empty(); //检查set是否为空
s.swap(s1); //交换两个容器
s.clear();
s.erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器
s.erase(beg, end);//删除[beg, end)的所有元素,返回下一个元素的迭代器
s.erase(elem); //删除容器中值为elem的元素
s.find(key); //返回该键的迭代器;若不存在,返回set.end()
s.count(key); //统计key元素的个数
源码剖析
template<class Key,
class Compare = less<Key>,
class Alloc = alloc>
class set
public:
typedef Key key_type;
typedef Key value_type;
typedef Compare key_compare;
typedef Compare value_compare;
private:
typedef rb_tree <key_type,
value_type,
identity<value_type>,
key_compare,
Alloc> rep_type;
rep_type t; // 内部rb_tree容器
public:
typedef typename rep_type::const_iterator iterator;
;
set
容器的模板参数推导过程如下:
容器map和multimap
概述
容器map
和multimap
以rb_tree
为底层容器,因此其中元素是有序的,排序的依据是key
map
和multimap
提供迭代器iterator
用以顺序遍历容器.无法使用iterator
改变元素的key
,但可以用它来改变元素的data
,因为map
和multimap
内部自动将key
的类型设为const
map
元素的key
必须独一无二,因此其insert()
调用的是内部rb_tree
的insert_unique()
方法;
multimap
元素的key
可以重复,因此其insert()
调用的是内部rb_tree
的insert_equal()
方法
使用
#include <map>
#include <algorithm>
#include <iostream>
using namespace std;
void main()
//初始化
map<int, int> m; //默认构造
map<int, int> m1(m); //拷贝构造
map<int, int> m2 = m1; //重载等号操作符
//遍历
for (auto i : m)
cout << i.second << endl;
for (auto i = m.begin(); i != m.end(); i++)
cout << (*i).second << endl;
//成员函数
m.size(); //返回容器中元素个数
m.empty(); //判断容器是否为空
m.swap(m1); //交换两个容器
m.insert(pair<int, int>(1,5));//插入元素5
m.clear();
m.erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器
m.erase(beg, end); //删除区间[beg,end)中所有元素,返回下一元素的迭代器
m.erase(key); //删除容器中值为key的元素
m.find(key); //查找key是否存在,若存在,返回该键的迭代器;若不存在,返回set.end()
m.count(key); //统计key元素的个数
源码剖析
template<class Key,
class T,
class Compare = less<Key>,
class Alloc = alloc>
class map
public:
typedef Key key_type;
typedef T data_type;
typedef T mapped_type;
typedef pair<const Key, T> value_type;
typedef Compare key_compare;
private:
typedef rb_tree <key_type,
value_type,
select1st<value_type>,
key_compare,
Alloc> rep_type;
rep_type t; // 内部rb_tree容器
public:
typedef typename rep_type::iterator)
iterator;
;
map
容器的模板参数推导过程如下:
以上是关于STL—set和map使用及源码剖析的主要内容,如果未能解决你的问题,请参考以下文章
C++源码剖析——unordered_map和unordered_set