STL源碼剖析(十八)關聯式容器之hash_map、hash_multimap

STL源碼剖析(十八)關聯式容器之hash_map、hash_multimap


map 和 set 的區別就是,set 的 value 中 只有 key 沒有 data,而 map 的 value 既有 key 又有 data,每一個元素都是一個對組

一、hash_map、hash_multimap的數據結構

hash_map的定義如下

template <class Key, class T, class HashFcn = hash<Key>,
          class EqualKey = equal_to<Key>,
          class Alloc = alloc>
class hash_map
{
  ...
private:
  typedef hashtable<pair<const Key, T>, Key, HashFcn,
                    select1st<pair<const Key, T> >, EqualKey, Alloc> ht;
  ht rep;
  ...
};

它們的成員變量只有一個哈希表,下面解析一下哈希表的模板參數

哈希表的模板參數定義如下

template <class Value, class Key, class HashFcn,
          class ExtractKey, class EqualKey,
          class Alloc>
class hashtable {
  ...
};
  • Value:包含 key + data,hash_map 指定的是 pair<const Key, T>,一個對組,注意裏面的 key 是 const 類型,因爲 key 是不允許被修改的

  • Key:鍵值

  • HashFcn:哈希函數,hash_map 指定的是 hash<Key>,用於生成哈希值,這個上一篇文章已經講解過了,這裏不再講解

  • ExtractKey:從 value 中獲取 key,hash_map 的定義爲 select1st<pair<const Key, T> >,因爲每個元素都是 key 加 data,所以獲取鍵值就從對組中取出第一個元素就行,select1st 的定義如下

    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;
      }
    };
    
  • EqualKey:判斷 key 是否相等,hash_map 的定義爲 equal_to<Key> ,定義如下

    template <class T>
    struct equal_to : public binary_function<T, T, bool> {
        bool operator()(const T& x, const T& y) const { return x == y; }
    };
    

hash_mulitmap 的數據結構和 hash_map 是一樣的,這裏不再列出

二、hash_map、hash_multimap的迭代器

hash_map 和 hash_multimap 的迭代器都是一樣的,定義如下

typedef typename ht::iterator iterator;

它們都是直接使用哈希表的迭代器

如果要修改對應的data,可以這樣做

it->second = xxx;

三、hash_map、hash_multimap的操作

hash_map 和 hash_multimap 的操作基本是相同的,只是插入元素的操作不同,這裏相同的部分只會列處 hash_map

3.1 構造函數

hash_map() : rep(100, hasher(), key_equal()) {}

初始化哈希表

3.2 析構函數

hash_map 和 hash_multimap 是沒有析構函數的,在釋放 hash_map 和 hash_multimap 對象的時候,會自動析構釋放成員變量,所以哈希表會被自動析構釋放

3.3 插入元素

hash_map 的 insert

pair<iterator, bool> insert(const value_type& obj)
    { return rep.insert_unique(obj); }

因爲不允許鍵值重複,所以調用的哈希表的 insert_unique 操作

hash_multimap 的 insert

iterator insert(const value_type& obj) { return rep.insert_equal(obj); }

允許鍵值重複,所以調用的哈希表的 insert_equal 操作

3.4 刪除元素

size_type erase(const key_type& key) {return rep.erase(key); }

通過調用哈希表的 erase 完成操作

3.5 其他操作

begin

iterator begin() { return rep.begin(); }

end

iterator end() { return rep.end(); }

find

iterator find(const key_type& key) { return rep.find(key); }

可以看到,絕大數操作都是轉而調用哈希表完成的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章