C++ unordered_map、mulitimap、set、map

一、关联式容器

  在C++ STL中,有几类常见的关联式容器:unordered_map、mulitimap、set

二、红黑树 RB_tree

  红黑树是平衡二分查找树中常被使用的一种。平衡二分搜索树的特征:排列规则有利search和insert,并保持适度平衡——无任何节点过深。

  提供遍历操作和interators,按正常规则遍历,便能获得排序状态。map允许元素的data被改变,只有元素的value才是不可以被改变的。

2.1 rb_tree源码实现

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; //rb_tree的大小(节点数量)
        link_type header;
        Compare key_compare; //key的大小比较规则
};

三、set,multiset

  set,multiset以rb_tree为底层结构,因此具有元素自动排序的特性。set,multiset的key和value合二为一,value就是key,所以无法使用interator改变value值。

  set的元素key必须独一无二,multiset的元素key可以重复。

set的类模板源码大致如下(不一定准确):

template <class Key,
                class Compare=less<Key>,
                class Alloc=alloc>
class set {
    typedef Key key_type;
    typedef Key Value_type;
    typedef Compare key_compare;
    typedef Compare value_compare;
private:
     typedef rb_tree<key_type,value_type,...> rep_type;
public:
    typedef typename rep_type::const_iterator iterator;
...
}    

  所以实际上定义的set<int> set,底层是定义了set<int,less<int>,alloc> set, 里面内含了红黑树的结构。set的所有操作,都转为底层红黑树的操作,从这层意义看,set未尝不是个 container adapter。

 四、map,multimap

  map,multimap以红黑树为底层结构,因此有元素自动排序的特性,排序的依据是key。按照iterator的++遍历,便能获得排序状态。

注意,无法使用map/multimap的iterator改变元素的key值,但是可以用它来改变元素的data。因此map,multimap内部自动将user指定的key type设为const以此来禁止user对元素的key赋值。

  map的元素key必须独一无二,multimap的元素key可以重复。

  map的类模板源码大致如下(不一定准确):

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;
    //select1st意味着取出第一个key
    rep_type t;
public:
    typedef typename rep_type::iterator iterator;
...
};

  所以实际上定义的map<int,string> map,底层是定义了map<int, string, less<int>,alloc> imap, 里面内含了红黑树的结构。

map可以有着特殊的操作符[ ],当使用key值做索引搜索目标值,如果map中没有对应的值则会自动创建一个,注意,multimap不支持[ ]操作符,只能使用insert(pair...)的形式。

五、容器hashtable

 

posted @ 2022-11-06 21:57  寄寓黄昏喵  阅读(67)  评论(0编辑  收藏  举报