Chapter 5:关联式容器之 map 和 multimap

一:map

1:map的特性是,所有元素都会根据元素的键值自动被排序。map 的所有元素都是 pair,同时拥有实值(value)和键值(key)。pair 的第一元素被视为键值,第二元素被视为实值。map 不允许两个元素拥有相同的键值。pair 的定义代码如下:

template <class T1, class T2>
struct pair {
    typedef T1  first_type;
    typedef T2  second_type;

    T1 first;       //注意,它是 public
    T2 second;  //注意,它是public
    pair() : first(T1()), second(T2()) {}
    pair(const T1& a, const T2& b) : first(a), second(b) {}
};

2:我们不能通过 map 的迭代器修改键值,因为键值关系到 map 元素的排列规则,但我们可以通过 map 迭代器修改实值(value),因为 map 元素的实值并不影响 map 元素的排列规则,因此 map iterators 既不是一种 constant iterators,也不是一种 mutable iterators;

3:由于 RB-tree 是一种平衡二叉搜索树,自动排序的效果很不错,所以标准的 STL map 即以 RB-tree 为底层机制。又由于 map 所开放的各种操作接口,RB-tree 也都提供了,所以几乎所有的 map 操作行为,都只是转调用 RB-tree 的操作行为而已。RB-tree 的每一个节点内容都是 pair

4:map 的源代码如下:

//缺省使用递增排序
template <class Key, class T, class Compare = less<Key>, class Alloc = alloc>
class map {
public:
        //typedefs
        typedef Key     key_type;       //键值型别
        typedef T       data_type;      //数据(实值)型别
        typedef T       mapped_type;    //
        typedef pair<const Key, T> value_type;  //元素型别(键值/实值)
        //键值不可改变,所以用 const Key
        typedef Compare key_compare;    //键值比较函数

        //以下定义一个 functor,其作用就是调用“元素比较函数”
        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:
        //以 map 元素型别(一个pair)的第一型别,作为 RB-tree 节点的键值型别
        typedef rb_tree<key_type, value_type, select1st<value_type>, key_compare, Alloc> rep_type;
        rep_type t;     //以红黑树(RB-tree)表现 map

public:
        typedef typename rep_type::pointer              pointer;
        typedef typename rep_type::const_pointer        const_pointer;
        typedef typename rep_type::reference            reference;
        typedef typename rep_type::const_reference      const_reference;
        typedef typename rep_type::iterator             iterator;
        //注意上一行,map 并不像 set 一样将 iterator 定义为 RB-tree 的
        //const_iterator。因为它允许用户通过其迭代器修改元素的实值(value)
        typedef typename rep_type::const_iterator       const_iterator;
        typedef typename rep_type::reverse_iterator     reverse_iterator;
        typedef typename rep_type::const_reverse_iterator       const_reverse_iterator;
        typedef typename rep_type::size_type            size_type;
        typedef typename rep_type::difference_type      difference_type;

        //allocation/deallocation
        //注意,map 一定要使用底层 RB-tree 的insert_unique()而非insert_equal()
        //multimap 才使用 insert_equal()
                //因为 map 不允许相同键值存在,multimap 才允许相同键值存在

        map() : t(Compare()) {}
        explicit map(const Compare& comp) : t(comp) {}

        template <class InputIterator>
        map(InputIterator first, InputIterator last) : t(compare()) { t.insert_unique(first, last); }

        template <class InputIterator>
        map(InputIterator first, InputIterator last, const Compare& comp) : t(comp) { t.insert_unique(first, last); }

        map(const map<Key, T, Compare, Alloc>& x) : t(x.t) {}
        map<Key, T, Compare, Alloc>& operator=(const map<Key, T, Compare, Alloc>& x) {
                t = x.t;
                return *this;
        }

        //accessors:
        //以下所有的 map 操作行为,RB-tree 都已提供,map 只要转调用即可
        key_compare key_comp() const { return t.key_comp(); }
        value_compare value_comp() const { return value_compare(t.key_comp()); }
        iterator begin() { return t.begin(); }
        const_iterator begin() const { return t.begin(); }
        iterator end() { return t.end(); }
        const_iterator end() const { return t.end(); }
        reverse_iterator rbegin() { return t.rbegin(); }
        const_reverse_iterator rbegin() const { return t.rbegin(); }
        reverse_iterator rend() { return t.rend(); }
        const_reverse_iterator redn() const { return t.rend(); }
        bool empty() const { return t.empty(); }
        size_type size() const { return t.size(); }
        size_type max_size() const { return t.max_size(); }
        //注意,以下下标(subscript)操作符
        T& operator[](const key_type& k) {
                return (*((insert(value_type(k, T()))).first)).second;
        }
        void swap(map<Key, T, Compare, Alloc>& x) { t.swap(x.t); }

        //insert / erase

        //注意以下 insert 操作返回的型别
        pair<iterator, bool> insert(const value_type& x) {
                return t.insert_unique(x);
                        }
        iterator insert(iterator position, const value_type& x) {
                return t.insert_unique(position, x);
        }
        template <class InputIterator>
        void insert(InputIterator first, InputIterator last) {
                t.insert_unique(first, last);
        }

        void erase(iterator position) { t.erase(position); }
        size_type erase(const key_type& x) { return t.erase(x); }
        void erase(iterator first, iterator last) { t.erase(first, last); }
        void clear() { t.clear(); }

        //map operations:
        iterator find(const key_type& x) { return t.find(x); }
        const_iterator find(const key_type& x) const { return t.find(x); }
        size_type count(const key_type& x) { return t.count(x); }
        iterator lower_bound(const key_type& x) { return t.lower_bound(x); }
        const_iterator lower_bound(const key_type& x) const {
                return t.lower_bound(x);
        }
        iterator upper_bound(const key_type& x) { return t.upper_bound(x); }
        const_iterator upper_bound(const key_type& x) const {
                return t.upper_bound(x);
        }


        pair<iterator, iterator> equal_range(const key_type& x) {
                return t.equal_range(x);
        }
        pair<const_iterator, const_iterator> equal_range(const key_type& x) const {
                return t.equal_range(x);
        }
        friend bool operator==(const map&, const map&);
        friend bool operator<(const map&, const map&);
};

template <class Key, class T, class Compare, class Alloc>
inline bool operator==(const map<Key, T, Compare, Alloc>& x, const map<Key, T, Compare, Alloc>& y)
{
        return x.t == y.t;
}

template <class Key, class T, class Compare, class Alloc>
inline bool operator<(const map<Key, T, Compare, Alloc>& x, const map<Key, T, Compare, Alloc>& y)
{
        return x.t < y.t;
}

二:multimap

1:multimap 的特性以及用法与 map 完全相同,唯一的差别在于它允许键值重复,因此它的插入操作采用的是底层机制 RB-tree 的insert_equal()而非insert_unique()

2:下面是 multimap 的源代码提要,只列出了与 map 不同之处:

template <class Key, class T, class Compare = less<Key>, class Alloc = alloc>
class multimap {
public:
        //typedefs
        ... //(与 set 相同)

        // allocation / deallocation
        //注意,multimap 一定要使用 insert_equal()而不是insert_unique()
        // map 才使用 insert_unique()

        template <class InputIterator>
        multimap(InputIterator first, InputIterator last)
        : t(compare()) { t.insert_equal(first, last); }

        template <class InputIterator>
        multimap(InputIterator first, InputIterator last, const Compare& comp)
        : t(comp) { t.insert_equal(first, last); }
        ... //(其它与 map 相同)

        // insert/erase
        iterator insert(const value_type& x) {
                return t.insert_equal(x);
        }
        iterator insert(iterator position, const value_type& x) {
                return t.insert_equal(position, x);
        }
        template <class InputIterator>
        void insert(InputIterator first, InputIterator last) {
                t.insert_equal(first, last);
        }
        ...//(其它与 map 相同)
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值