当前位置:   article > 正文

STL源码剖析——散列表hashtable_stl中关于散列表是怎么定义的

stl中关于散列表是怎么定义的

前言

    前面介绍的关联容器setmultisetmapmultimap的底层机制都是基于RB-Tree红黑树,虽然能够实现在插入、删除和搜素操作能够达到对数平均时间,可是要求输入数据有足够的随机性。本文介绍的hash table不需要要求输入数据具有随机性,在插入、删除和搜素操作都能达到常数平均时间。本文介绍的hash table是来自SGI STL中的<stl_hashtable.h>文件,在这里为了避免冲突(即不同元素映射到相同的键值位置),采用了拉链法来解决冲突问题。SGI中实现hash table的方式,在每个表格元素中维护一个链表, 然后在链表上执行元素的插入、搜寻、删除等操作,该表格中的每个元素被称为桶(bucket)。有关hash table的介绍可往前面博文散列表查看。

hashtable散列表源码剖析

  1. #ifndef __SGI_STL_INTERNAL_HASHTABLE_H
  2. #define __SGI_STL_INTERNAL_HASHTABLE_H
  3. // Hashtable class, used to implement the hashed associative containers
  4. // hash_set, hash_map, hash_multiset, and hash_multimap.
  5. //SGI STL的hashtable的实现方法是拉链法.
  6. //拉链法可以避免hashtable的冲突问题,即不同数据映射到同一的hash值
  7. //有关hashtable的介绍见前文:
  8. //http://blog.csdn.net/chenhanzhun/article/details/38091431
  9. #include <stl_algobase.h>
  10. #include <stl_alloc.h>
  11. #include <stl_construct.h>
  12. #include <stl_tempbuf.h>
  13. #include <stl_algo.h>
  14. #include <stl_uninitialized.h>
  15. #include <stl_function.h>
  16. #include <stl_vector.h>
  17. #include <stl_hash_fun.h>
  18. __STL_BEGIN_NAMESPACE
  19. //hashtable中链表的节点结构
  20. //类似于单链表的节点结构
  21. template <class _Val>
  22. struct _Hashtable_node
  23. {
  24. _Hashtable_node* _M_next;//指向下一节点
  25. _Val _M_val;//节点元素值
  26. };
  27. //这里使用前置声明, 避免在后面交叉引用会导致编译错误
  28. template <class _Val, class _Key, class _HashFcn,
  29. class _ExtractKey, class _EqualKey, class _Alloc = alloc>
  30. class hashtable;
  31. template <class _Val, class _Key, class _HashFcn,
  32. class _ExtractKey, class _EqualKey, class _Alloc>
  33. struct _Hashtable_iterator;
  34. template <class _Val, class _Key, class _HashFcn,
  35. class _ExtractKey, class _EqualKey, class _Alloc>
  36. struct _Hashtable_const_iterator;
  37. //hashtable迭代器定义
  38. //注意:hash table迭代器没有提供后退操作operator--
  39. //也没用提供逆向迭代器reverse iterator
  40. template <class _Val, class _Key, class _HashFcn,
  41. class _ExtractKey, class _EqualKey, class _Alloc>
  42. struct _Hashtable_iterator {
  43. //内嵌类型别名
  44. typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
  45. _Hashtable;
  46. typedef _Hashtable_iterator<_Val, _Key, _HashFcn,
  47. _ExtractKey, _EqualKey, _Alloc>
  48. iterator;
  49. typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
  50. _ExtractKey, _EqualKey, _Alloc>
  51. const_iterator;
  52. typedef _Hashtable_node<_Val> _Node;
  53. typedef forward_iterator_tag iterator_category;//采用正向迭代器
  54. typedef _Val value_type;
  55. typedef ptrdiff_t difference_type;
  56. typedef size_t size_type;
  57. typedef _Val& reference;
  58. typedef _Val* pointer;
  59. _Node* _M_cur;//当前迭代器所指位置
  60. _Hashtable* _M_ht;//hashtable中的位置,控制访问桶子连续性
  61. _Hashtable_iterator(_Node* __n, _Hashtable* __tab)
  62. : _M_cur(__n), _M_ht(__tab) {}
  63. _Hashtable_iterator() {}
  64. //返回当前节点元素值的引用
  65. reference operator*() const { return _M_cur->_M_val; }
  66. #ifndef __SGI_STL_NO_ARROW_OPERATOR
  67. pointer operator->() const { return &(operator*()); }
  68. #endif /* __SGI_STL_NO_ARROW_OPERATOR */
  69. //操作符重载定义在后面定义
  70. iterator& operator++();
  71. iterator operator++(int);
  72. //比较两个迭代器是否指向同一个节点
  73. bool operator==(const iterator& __it) const
  74. { return _M_cur == __it._M_cur; }
  75. bool operator!=(const iterator& __it) const
  76. { return _M_cur != __it._M_cur; }
  77. };
  78. //下面是const iterator的定义,基本和上面相同
  79. template <class _Val, class _Key, class _HashFcn,
  80. class _ExtractKey, class _EqualKey, class _Alloc>
  81. struct _Hashtable_const_iterator {
  82. typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
  83. _Hashtable;
  84. typedef _Hashtable_iterator<_Val,_Key,_HashFcn,
  85. _ExtractKey,_EqualKey,_Alloc>
  86. iterator;
  87. typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
  88. _ExtractKey, _EqualKey, _Alloc>
  89. const_iterator;
  90. typedef _Hashtable_node<_Val> _Node;
  91. typedef forward_iterator_tag iterator_category;
  92. typedef _Val value_type;
  93. typedef ptrdiff_t difference_type;
  94. typedef size_t size_type;
  95. typedef const _Val& reference;
  96. typedef const _Val* pointer;
  97. const _Node* _M_cur;
  98. const _Hashtable* _M_ht;
  99. _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab)
  100. : _M_cur(__n), _M_ht(__tab) {}
  101. _Hashtable_const_iterator() {}
  102. _Hashtable_const_iterator(const iterator& __it)
  103. : _M_cur(__it._M_cur), _M_ht(__it._M_ht) {}
  104. reference operator*() const { return _M_cur->_M_val; }
  105. #ifndef __SGI_STL_NO_ARROW_OPERATOR
  106. pointer operator->() const { return &(operator*()); }
  107. #endif /* __SGI_STL_NO_ARROW_OPERATOR */
  108. const_iterator& operator++();
  109. const_iterator operator++(int);
  110. bool operator==(const const_iterator& __it) const
  111. { return _M_cur == __it._M_cur; }
  112. bool operator!=(const const_iterator& __it) const
  113. { return _M_cur != __it._M_cur; }
  114. };
  115. // Note: assumes long is at least 32 bits.
  116. // 注意:假设long至少为32-bits, 可以根据自己需要修改
  117. //定义28个素数用作hashtable的大小
  118. enum { __stl_num_primes = 28 };
  119. static const unsigned long __stl_prime_list[__stl_num_primes] =
  120. {
  121. 53ul, 97ul, 193ul, 389ul, 769ul,
  122. 1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
  123. 49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
  124. 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
  125. 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
  126. 1610612741ul, 3221225473ul, 4294967291ul
  127. };
  128. //返回大于n的最小素数
  129. inline unsigned long __stl_next_prime(unsigned long __n)
  130. {
  131. const unsigned long* __first = __stl_prime_list;
  132. const unsigned long* __last = __stl_prime_list + (int)__stl_num_primes;
  133. const unsigned long* pos = lower_bound(__first, __last, __n);
  134. /*
  135. 上面的lower_bound调用的是STL中的算法lower_bound();
  136. 该算法的功能:
  137. Returns an iterator pointing to the first element in the range [first,last) which does not compare less than val.
  138. The elements in the range shall already be sorted according to this same criterion (operator< or comp)
  139. 即返回在[first,last)范围内第一个不小于val的位置
  140. 注意:调用该算法之前,[first,last)范围里面的元素必须已排序
  141. 该算法的原型如下:
  142. 第一个版本:采用默认比较准则operator<
  143. template <class ForwardIterator, class T>
  144. ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last,
  145. const T& val);
  146. 第二版本:采用用户指定的比较函数comp
  147. te
声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号