在前面【STL】RB-tree(红黑树)和hashtable(哈希表)的实现原理我们对于RB-tree的设计与实现都有了一定的了解,那么这一节中所要解析的set以及map看起来就简单了许多,因为这两者都是以RB-tree作为其底层数据结构,大部分操作直接调用RB-tree的操作实现的,只针对set及map的性质及特有操作进行解析。
template <class Key, class Compare = less<key>, class Alloc = allloc>
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, identify<value_type>,
key_compare, Alloc> rep_type;
rep_type t; //采用红黑树来表现set
public:
//...
typedef typename rep_type::const_iterator iterator; //定义为const_iterator,不允许更改
//...
//以下列举出的构造函数与插入均使用insert_unique方式
template <class InputIterator>
set(InputIterator first, InputIterator lst)
: t(Compare()) { t.insert_unique(first, last); }
//...
iterator insert(iterator position, const value_type& x) { //其中一个插入操作版本
typedef typename rep_type::iterator rep_iterator;
return t.insert_unique((rep_iterator&)position, x);
}
//...
void erase(iterator position) { //其中一个版本的删除操作
typedef typename rep_type::iterator rep_iterator;
t.erase((rep_iterator&)position);
}
//...
//在first和last的前闭后开的区间中进行二分查找第一个不小于x的值
iterator lower_bound(const key_type& x) const {
return t.low_bound(x);
}
//在first和last的前闭后开的区间中进行二分查找第一个大于x的值
iterator upper_bound(const key_type& x) const {
return t.upper_bound(x);
}
//返回上述两种方式返回的迭代器区间
pair<iterator, iterator> equal_range(const key_type& x) const {
return t.equal_range(x);
}
//...
};
template <class T1, class T2>
struct pair {
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair() : first(T1()), second(T2()) {}
pair(const T1& a, const T2& b) : first(a), second(b) {}
};
template <class Key, class T, class Compare = less<key>, class Alloc = allloc>
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; //键值比较函数
//调用元素比较函数
class value_compare
: public binary_function<value_type, value_type, bool> {
friend class map<Key, T, Compare, Alloc>;
protected:
Compare comp;
value_compare(Compare c) : comp(c) {}
public:
bool operator() (const value_type& x, const value_type& y) const {
return comp(x.first, y.first);
}
};
private:
//...
typedef rb_tree<key_type, value_type, select1st<value_type>,
key_compare, Alloc> rep_type;
rep_type t; //采用红黑树来表示map
public:
//...
typedef typename rep_type::iterator iterator; //定义为iterator,允许更改
//...
//以下列举出的构造函数与插入均使用insert_unique方式
template <class InputIterator>
map(InputIterator first, InputIterator lst)
: t(Compare()) { t.insert_unique(first, last); }
//...
value_compare value_comp() const { return value_compare(t.key_compare()); } //元素比较
//...
T& operator[] (const key_type& k) { //下标操作符
return (*((insert(value_type(k, T()))).first)).second;
}
iterator insert(iterator position, const value_type& x) { //其中一个插入操作版本
return t.insert_unique(position, x);
}
pair<iterator, bool> insert(const value_type& x) { //另一个插入操作版本
return t.insert_unique(x); }
//...
void erase(iterator position) { //其中一个版本的删除操作
typedef typename rep_type::iterator rep_iterator;
t.erase((rep_iterator&)position);
}
//...
//在first和last的前闭后开的区间中进行二分查找第一个不小于x的值
iterator lower_bound(const key_type& x) const {
return t.low_bound(x);
}
//在first和last的前闭后开的区间中进行二分查找第一个大于x的值
iterator upper_bound(const key_type& x) const {
return t.upper_bound(x);
}
//返回上述两种方式返回的迭代器区间
pair<iterator, iterator> equal_range(const key_type& x) const {
return t.equal_range(x);
}
//...
};
pair<iterator, bool> insert(const value_type& x)
{ return t.insert_unique(x); }
我们可以观察上面的函数,其返回值是一个pair类型,其第一个值为迭代器类型,第二个值为bool类型,其中bool类型代表此次插入是否成功,而迭代器类型则表示指向被插入的那个元素
用法有两种:
map<string, int> simap;
simap[string("jjhou")] = 1; //左值运用
int number = simap[string("jjhou")]; //右值引用
下标操作函数:
T& operator[] (const key_type& k) {
return (*((insert(value_type(k, T()))).first)).second;
}
template < class Key, class Compare = less<Key>, class Alloc = alloc>
class multiset {
public:
//...
template <class InputIterator>
multiset(InputIterator first, InputInterator last)
: t(Compare()) { t.insert_equal(first, last); }
//...
};
template < class Key, class Compare = less<Key>, class Alloc = alloc>
class multimap {
public:
//...
template <class InputIterator>
multiset(InputIterator first, InputInterator last)
: t(Compare()) { t.insert_equal(first, last); }
//...
};
参考资料:
《STL源码剖析》 - 侯捷