红黑树
- 红黑树是高度平衡的二叉搜索树。它的排列规则有利于serach和insert,并保持深度平衡即没有任何一个节点太深。
- 红黑树提供遍历操作及迭代器,遍历得到一个有序序列(中序遍历)
- 不应该使用迭代器修改红黑树节点的值,对于map,可以修改value,对于set,不能更改,防止破坏红黑树的有序性。
- 红黑树提供两种插入操作,一种是insert_unique()另一种是insert_equal()。前者表示节点的key在整棵树中是独一无二的,后者允许节点的key重复,且相同key一定是相邻的。
template<class Key, class Value, class KeyOfValue, class Compare, 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;
link_type header;
Compare ker_compare;
...
}
- 红黑树直接使用示例(2.9版),新版本有一些函数和类的名称变了
rb_tree<int, int, identity<int>, less<int>, alloc> myTree;
template <class Arg, class Result>
struct unary_function{
typedef Arg argument_type;
typedef Result result_type;
};
template<class T>
struct identity:public unary_function<T, T>{
const T& operator()(const T& x) const {return x;}
};
template<class Arg1, class Arg2, class Result>
struct binary_function{
typedef Arg1 first_argument_type;
typedef Arg2 second_argument_type;
typedef Result reault_type;
};
template<class T>
struct less: public binary_function<T, T, bool>{
bool operator()(const T& x, const T& y) const
{ return x < y; }
};
---------------------测试程序---------------------------
rb_tree<int, int, identity<int>, less<int>> itree;
cout<< itree.empty() << endl;
cout<< itree.size() << endl;
itree.insert_unique(3);
itree.insert_unique(8);
itree.insert_unique(5);
itree.insert_unique(9);
itree.insert_unique(13);
itree.insert_unique(5);
cout<< itree.empty() <<endl;
cout<< itree.size() <<endl;
cout<<itree.count(5) << endl;
itree.insert_equal(5);
itree.insert_equal(5);
cout<< itree.size() <<endl;
cout<< itreecount(5) <<endl;
- G4.9版
- 符合Handle and Body法则,将定义和实现分离
- 在4.9中红黑树是24个字节,三个指针和一个枚举类型
set与multiset
- set/multiset是以红黑树为底层结构,因此,元素有自动排序的特性。排序的依据是key,且value就是key
- set/multiset提供遍历操作及iterators。按正常规则(++iterators),便能得到排序状态。
- 无法使用set/multiset的iterator改变元素值(因为ke有其特殊的排列规则)set/multiset的iterator的底部红黑树是const_iterator,就是为了禁止用户对元素赋值
- set的key必需独一无二,它的insert()用的是红黑树的insert_unique()
- multiset的key可以重复,它的insert()用的是红黑树的insert_equal()
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;
public:
typedef typename rep_type::const_iterator iterator;
...
};
map和multimap
- map和multimap是以红黑树为底层结构,因此元素有自动排序特性,排序的依据是key
- map/multimap提供遍历操作及iterators,按++ite的方式遍历,可得到顺序序列
- 无法使用iterator改变元素的key,但是可以用它来改变元素的data。因此map/multimap内部自动将用户指定的key_type设置为const,实现禁止用户对元素key赋值。
template<class Key, class T, class Compare = less<Key>m 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;
public:
typedef typename rep_type::iterator iterator;
...
};
template<class Arg, class Result>
struct unary_function{
typedef Arg atgument_type;
typedef Result result_type;
};
template <class Pair>
struct select1st:public unary_function<Pair, typename Pair::first_type>{
const typename Pair::first_type& operator()(const Pair& x) const
{ return x.first; }
};
- map的[ ] 操作符
- 返回key对应的value,如果key不存在,将这一对数据插入到map中
- [ ]操作符先调用lower_bound,查找key,如果找到就返回对应的value,没找到就返回最适合的插入的位置,后调用insert
- 如果像map中插入元素,insert的效率高于[ ]操作符
- [ ]操作符只有map和unordered_map有,对于multimap,可能有多个value与相同的key关联