开链法(哈希桶)是解决哈希冲突的常用手法,结构如下:

wKiom1c1z0jiqWopAAAtDyd3Kyk688.png

    数据结构的设计思路是这样的,定义一个K—V的链式节点(Node),以数组方式存储节点指针

    实现代码如下:

  1. #include<vector>
  2. #include"HashTable.h"
  3. size_t GetSize()
  4. {
  5. static size_t index = 0;
  6. const int _PrimeSize = 28;
  7. static const unsigned long _PrimeList[_PrimeSize] =
  8. {
  9. 53ul97ul193ul389ul769ul,
  10. 1543ul3079ul6151ul12289ul24593ul,
  11. 49157ul98317ul196613ul393241ul786433ul,
  12. 1572869ul3145739ul6291469ul12582917ul25165843ul,
  13. 50331653ul100663319ul201326611ul402653189ul805306457ul,
  14. 1610612741ul3221225473ul4294967291ul
  15. };
  16. return _PrimeList[index++];
  17. }
  18. template<class K,class V>
  19. struct HashBucketNode
  20. {
  21. HashBucketNode(const K& key, const V& value)
  22. :_key(key)
  23. , _value(value)
  24. , _next(NULL)
  25. {}
  26. K _key;
  27. V _value;
  28. HashBucketNode* _next;
  29. };
  30. template<class Kclass Vclass HashFunc = DefaultHash<K> >
  31. class HashBucket
  32. {
  33. public:
  34. typedef HashBucketNode<K,V> Node;
  35. HashBucket()
  36. :_size(0)
  37. {
  38. _tables.resize(0);
  39. }
  40. bool Push(const K& key, const V& value)
  41. {
  42. _CheckCapacity();
  43. size_t index = HashFunc()(key) % _tables.size();
  44. Node*cur = _tables[index];
  45. while (cur)
  46. {
  47. if (cur->_key == key&&cur->_value == value)
  48. return false;
  49. cur = cur->_next;
  50. }
  51. Node*tmp = new Node(key, value);
  52. if (_tables[index])
  53. {
  54. _tables[index]->_next = tmp->_next;
  55. }
  56. _tables[index] = tmp;
  57. ++_size;
  58. return true;
  59. }
  60. void Swap(HashBucket & h)
  61. {
  62. swap(_size, h._size);
  63. _tables.swap(h._tables);
  64. }
  65. Node* find(const K& key, const V& value)
  66. {
  67. size_t index = HashFunc()(key) % _tables.size();
  68. Node*cur = _tables[index];
  69. while (cur)
  70. {
  71. if (cur->_key == key&&cur->_value == value)
  72. return cur;
  73. cur = cur->_next;
  74. }
  75. return NULL;
  76. }
  77. bool Remove(const K& key)
  78. {
  79. size_t index = HashFunc()(key) % _tables.size();
  80. if (_tables[index])
  81. {
  82. if (_tables[index]->key == key)
  83. {
  84. Node*tmp = _tables[index];
  85. _tables[index] = tmp->_next;
  86. delete tmp;
  87. return true;
  88. }
  89. else
  90. {
  91. Node*cur = _tables[index];
  92. while (cur->_next)
  93. {
  94. if (cur->_next->_key == key)
  95. {
  96. Node*tmp = cur->_next;
  97. cur->_next = cur->_next->_next;
  98. delete tmp;
  99. return true;
  100. }
  101. cur = cur->_next;
  102. }
  103. }
  104. }
  105. return false;
  106. }
  107. protected:
  108. void _CheckCapacity()
  109. {
  110. if (_size >= _tables.size())
  111. {
  112. HashBucket tmp;
  113. tmp._tables.resize(GetSize());
  114. for (size_t i = 0; i < tmp._tables.size(); ++i)
  115. {
  116. Node*cur = tmp._tables[i];
  117. while (cur)
  118. {
  119. tmp.Push(cur->_key, cur->_value);
  120. cur = cur->_next;
  121. }
  122. }
  123. Swap(tmp);
  124. }
  125. }
  126. protected:
  127. vector<Node*> _tables;
  128. size_t _size;
  129. };

    如有不足希望指正,有疑问希望提出