hash_map的数据结构剖析及相关方法

hash_map是个很有用的索引结构,对于大规模数据检索的时候,用处大大的。本文基于源码的基础上,从数据结构开始剖析,进而介绍一些常用的方法。hash_map是基于hash_table基础上封装的方法类,下面看看hash_table的数据结构:

template<class _Key, class _Tp, class _HashFn = hash<_Key>,
           class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> >
    class hash_map
    {
    private:
      typedef hashtable<pair<const _Key, _Tp>,_Key, _HashFn,
                        _Select1st<pair<const _Key, _Tp> >,
                        _EqualKey, _Alloc> _Ht;


      _Ht _M_ht;
   }//hash_map 类的部分定义

   //下面是hashtable的数据结构定义
   template<class _Val>
    struct _Hashtable_node
    {    
      _Hashtable_node* _M_next;
      _Val _M_val;
    };//节点类
	
   template<class _Val, class _Key, class _HashFcn,
           class _ExtractKey, class _EqualKey, class _Alloc>
    class hashtable
	{
	  typedef _Hashtable_node<_Val> _Node; 
	  typedef vector<_Node*, _Nodeptr_Alloc> _Vector_type;
	  _Vector_type          _M_buckets;
	}
从上面可以看出:

hashtable的主要数据结构是个vector, 里面的元素是_Hashtable_node节点类型(链表的结构),并且此节点的value是个pair<key, value>类型。
结构图如下:

hash_map的数据结构剖析及相关方法_第1张图片



一些方法解析:

插入:

pair<iterator, bool>
      insert_unique(const value_type& __obj)
      {
		resize(_M_num_elements + 1);//重置hash_table的空间,有一张表__stl_prime_list,按照这张表进行动态的扩展空间。
								//每扩展一次,都重新开辟一个大点的空间,再重新hash,并把老的hash表拷贝过来。
		return insert_unique_noresize(__obj);//插入一个值(key, value)
      }
    template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
    pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator, bool>
    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
    insert_unique_noresize(const value_type& __obj)
    {
      const size_type __n = _M_bkt_num(__obj);//使用hash(key)%n 得到hashtable的位置
      _Node* __first = _M_buckets[__n];//使用节点指针,指向hashtable的指定位置
      
      for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)//判断是否有相等的key,有则返回相同key的节点指针。
	if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
	  return pair<iterator, bool>(iterator(__cur, this), false);
      
      _Node* __tmp = _M_new_node(__obj);//插入操作
      __tmp->_M_next = __first;
      _M_buckets[__n] = __tmp;
      ++_M_num_elements;
      return pair<iterator, bool>(iterator(__tmp, this), true);
    }



参考文章:

详细解说hash_map  http://blog.sina.com.cn/s/blog_4c98b9600100audq.html


你可能感兴趣的:(hash_map的数据结构剖析及相关方法)