
"我们都无可奈何地选择了,自己的人生。也无可奈何地出演自己拿到的剧本"
set是一种管理数据的容器,其底层是由红黑树来实现的。

1.set是按照一定序列存储的容器;
2.set中的元素(value)是唯一的;
3.......

与set相对的就是multiset

很显然,这个容器可以存放相同的数.
map也是一种关联式容器。和set不同的地方是,map会多一个修饰key的参数value
在map中,这两个值 会被封装到一个pair中,本质上pair 就是一个结构体

1.和set一样 底层用红黑树实现
2.只能存一个key值。但可以存同一value
3.map支持[]访问
使用map的时候,需要注意的是 他底层去重载的[].

[],返回的是pair中value的值 , 并可以对其进行修改。
与map相对的也有mutltimap:
我们在实现红黑树的时候,对于 节点存储的模板为K,V。
怎么能让底层,去同时封装 不同存储类型的容器?!
- //template
- template<class T>
- struct RBTreeNode
- {
- RBTreeNode
* _left; - RBTreeNode
* _right; - RBTreeNode
* _parent; - T _data;
- Colour _col;
-
- RBTreeNode(const T& data)
- :_left(nullptr),
- _right(nullptr),
- _parent(nullptr),
- _data(data),
- _col(RED)
- {}
- };
所以我么你相应对 红黑树的节点 再次泛化。因为它并不知道存储的是什么。
- template<class K,class T,class KeyOFT>
- struct RBTree
- {
- typedef RBTreeNode
Node; - RBTree()
- :_root(nullptr)
- {}
-
- Node* _root;
- }
我们不妨给红黑树的模板增加一个参数。让T 去决定 节点存什么!
既然T 是未知的,不同的T有不同的比较方法
KeyOFT----->就去弥补 实现不同T数据 的比较。(实现的仿函数)
- template<class K,class T>
- class map
- {
- public:
- struct MapOFT
- {
- const K& operator()(const pair
& kv) - {
- return kv.first;
- }
- };
- private:
- RBTree
const K, V>, MapOFT> _m; - };
-
-
- template<class K>
- class set
- {
- public:
- struct SetOFT
- {
- K& operator()(const K& key)
- {
- return key;
- }
- };
- private:
- RBTree
_s; - };

三者关系整理成图就成了这样。 这种设计极为巧妙。
- template<class T,class Ref,class Ptr> //这里的迭代器封装和 list 极为相似 所谓的红黑树迭代器 就是指的 红黑树的节点
- struct _RBTree_iterator
- {
- typedef RBTreeNode
Node; - typedef _RBTree_iterator
Self; -
- _RBTree_iterator(Node* node)
- :_node(node)
- {}
- Node* _node;
-
- //opertor*
- Ref operator*()
- {
- return _node->_data;
- }
-
- Ptr operator->()
- {
- return &_node->_data;
- }
-
- bool operator!=(const Self& s)
- {
- return _node != s._node;
- }
-
- bool operator==(const Self& s)
- {
- return _node == s._node;
- }
-
- //难点;
- //set/map走的是一个 中序
- Self& operator++()
- {
- //此时_node 一定是最左节点
- if (_node->_right)
- {
- //此时如果不为空
- //证明右边还需要访问;
- Node* left = _node->_right;
- while (left->_left)
- {
- left = left->_left;
- }
-
- //此时找到 不为空的 右边的 第一个左边给 _node
- _node = left;
- }
- else
- {
- //由node出发
- //找到 右不为空的 父节点
- Node* cur = _node;
- Node* parent = cur->_parent;
-
- while (parent && cur == parent->_right)
- {
- cur = cur->_parent;
- parent = parent->_parent;
- }
-
- //下一次进来 就是去访问 _node 右根
- _node = parent;
- }
- return *this;
- }
-
- //右子树 根 左子树
- Self& operator--()
- {
- if (_node->_left)
- {
- Node* right = _node->_left;
- while (right->_right)
- {
- right = right->_right;
- }
-
- _node = right;
- }
- else
- {
- Node* cur = _node;
- Node* parent = cur->_parent;
-
- while (parent && cur == parent->_left)
- {
- cur = parent;
- parent = parent->_parent;
- }
- _node = parent;
- }
- return *this;
- }
- };

operator--;

- template
- class map
- {
- public:
- struct MapOFT
- {
- const K& operator()(const pair
& kv) - {
- return kv.first;
- }
- };
- //去红黑树 里找到 被封装好的 迭代器
- //此时要添加typename 因为迭代器实例化要在后面才进行
- // 这里要让编译器 这是个类
- typedef typename RBTree
, MapOFT>:: iterator iterator; -
- iterator begin()
- {
- return _m.begin();
- }
-
- iterator end()
- {
- return _m.end();
- }
-
- pair
insert(const pair& kv) - {
- return _m.insert(kv);
- }
-
- private:
- RBTree
, MapOFT> _m; - };
-
-
- template
- class set
- {
- public:
- struct SetOFT
- {
- const K& operator()(const K& key)
- {
- return key;
- }
- };
-
- typedef typename RBTree
::iterator iterator; -
- iterator begin()
- {
- return _s.begin();
- }
-
- iterator end()
- {
- return _s.end();
- }
-
- pair
insert(const K& key) - {
- return _s.insert(key);
- }
-
- private:
- RBTree
_s; - };
封装完成,我们就先拿来用一用;

map/set大致的玩法 行得通。
- V& operator[](const K& key)
- {
- pair
bool> ret = insert(make_pair(key,V())); - return (ret.first)->second;
- }
当然不能忘了map 重载的[];

这里的反向迭代器,并非来自迭代器萃取。而是由正向迭代器构造出来的。
- template<class Iterator>
- struct _RBTree_Reverse_iterator
- {
- //这里只设置了一个 模板参数
- //因为 反向迭代器 可以借用正向迭代器的 其他两个模板参数
- //同样这是 内置类型的模板 需要typename
- typedef typename Iterator::reference Ref;
- typedef typename Iterator::pointer Ptr;
-
- typedef _RBTree_Reverse_iterator
Self; - Iterator _it;
-
- };

- template<class Iterator>
- struct _RBTree_Reverse_iterator
- {
- //这里只设置了一个 模板参数
- //因为 反向迭代器 可以借用正向迭代器的 其他两个模板参数
- //同样这是 内置类型的模板 需要typename
- typedef typename Iterator::reference Ref;
- typedef typename Iterator::pointer Ptr;
-
- typedef _RBTree_Reverse_iterator
Self; -
- Iterator _it;
-
- //拿正向 迭代器初始化
- _RBTree_Reverse_iterator(Iterator it)
- :_it(it)
- {}
-
- //operator*
- Ref& operator*()
- {
- return *_it;
- }
-
- Self& operator++()
- {
- --_it;
- return *this;
- }
-
- Self& operator--()
- {
- ++_it;
- return *this;
- }
-
- bool operator!=(const Self& s) const
- {
- return _it != s._it;
- }
-
- bool operator==(const Self& s) const
- {
- return _it == s._it;
- }
-
- Ptr operator->()
- {
- return _it.operator->();
- }
- };
本篇也就到此为止。
感谢你的阅读
祝你好运~
