STL学习】自己动手C++编程实现hash table(散列表)

GI STL中散列表采用链接法解决冲突。结构中维护了一个vector,vector中每一个元素称为一个桶(bucket),它包含的是一个链表的第一个节点。

 

下面代码展示了自己编程实现的hash table,C++模板类封装。

 

如有错误,还请包涵和指正(E-Mail:xiajunhust@gmail.com)!

 

HashTable.h:

[cpp]  view plain copy print ?
 
  1. //《STL源码剖析》5.7 hashtable编程实现  
  2. //Author:江南烟雨  
  3. //E-Mail:xiajunhust@gmail.com  
  4.   
  5. #include <iostream>  
  6. #include <algorithm>  
  7. #include <vector>  
  8.   
  9. //hash table中链表节点数据结构定义  
  10. template <class ValueType>  
  11. struct __hashtable_node{  
  12.     __hashtable_node *next;  
  13.     ValueType val;  
  14. };  
  15.   
  16. static const int __stl_num_primes = 28;//表格大小(28个质数)  
  17. //28个质数  
  18. static const unsigned long __stl_prime_list[__stl_num_primes] = {  
  19.     53,         97,           193,         389,       769,  
  20.     1543,       3079,         6151,        12289,     24593,  
  21.     49157,      98317,        196613,      393241,    786433,  
  22.     1572869,    3145739,      6291469,     12582917,  25165843,  
  23.     50331653,   100663319,    201326611,   402653189, 805306457,   
  24.     1610612741, 3221225473ul, 4294967291ul  
  25. };  
  26.   
  27. //得出28个质数中不小于n的那个质数  
  28. inline unsigned long __get_next_prime(unsigned long n)  
  29. {  
  30.     const unsigned long *first = __stl_prime_list;  
  31.     const unsigned long *last = __stl_prime_list + __stl_num_primes;  
  32.     const unsigned long *pos = std::lower_bound(first,last,n);  
  33.   
  34.     return pos == last ? *(last - 1) : *pos;  
  35. }  
  36.   
  37. template <class T1,class T2>  
  38. void construct(T1 *p,const T2 &value)  
  39. {  
  40.     new (p) T1(value);  
  41. }  
  42.   
  43. template <class T>  
  44. void destroy(T* pointer)  
  45. {  
  46.     pointer->~T();//调用析构函数  
  47. }  
  48.   
  49. //hash函数定义  
  50. //都是仿函数  
  51. template <class KeyType>  
  52. struct hash{};  
  53.   
  54. //字符串要进行映射  
  55. inline size_t __stl_hash_string(const char *s)  
  56. {  
  57.     unsigned long h = 0;  
  58.     for (;*s;++s)  
  59.     {  
  60.         h = 5 * h + *s;  
  61.     }  
  62.   
  63.     return size_t(h);  
  64. }  
  65.   
  66. //类模板显示特化定义  
  67. template <>  
  68. struct hash<int>{  
  69.     size_t operator()(int x) const {return x;}  
  70. };  
  71.   
  72. template <>  
  73. struct hash<char *>{  
  74.     size_t operator()(const char *s) const {return __stl_hash_string(s);}  
  75. };  
  76.   
  77. template <>  
  78. struct hash<const char *>{  
  79.     size_t operator()(const char *s) const {return __stl_hash_string(s);}  
  80. };  
  81.   
  82. template <>  
  83. struct hash<char>{  
  84.     size_t operator()(char s) const {return s;}  
  85. };  
  86.   
  87. template <>  
  88. struct hash<unsigned char>{  
  89.     size_t operator()(unsigned char s) const {return s;}  
  90. };  
  91.   
  92. template <>  
  93. struct hash<signed char>{  
  94.     size_t operator()(signed char s) const {return s;}  
  95. };  
  96.   
  97. // C++ Standard 规定,每一个 Adaptable Unary Function 都必须继承此类别  
  98. template <class Arg,class Result>  
  99. struct unary_function{  
  100.     typedef Arg argument_type;  
  101.     typedef Result result_type;  
  102. };  
  103.   
  104. // C++ Standard 规定,每一个 Adaptable Binary Function 都必须继承此类别  
  105. template <class Arg1,class Arg2,class Result>  
  106. struct binary_function{  
  107.     typedef Arg1 first_argument_type;  
  108.     typedef Arg2 second_argument_type;  
  109.     typedef Result result_type;  
  110. };  
  111.   
  112. //从节点中取出键值的仿函数定义  
  113. //identity function;任何数值通过此函数式后,不会发生任何改变  
  114. template <class T>  
  115. struct identity:public unary_function<T,T>  
  116. {  
  117.     const T& operator()(const T& x) const{return x;}  
  118. };  
  119.   
  120. //判断键值是否相等的仿函数定义  
  121. template <class T>  
  122. struct equal_to:public binary_function<T,T,bool>{  
  123.     bool operator()(const T& x,const T& y) const{return x == y;}  
  124. };  
  125.   
  126. //比较字符串是否相等的仿函数  
  127. struct eqstr{  
  128.     bool operator()(const char *s1,const char *s2)const  
  129.     {  
  130.         return strcmp(s1,s2) == 0;  
  131.     }  
  132. };  
  133.   
  134. //hash table数据结构定义  
  135. //模板参数:  
  136. //ValueType:节点的实值型别  
  137. //KeyType:节点的键值型别  
  138. //HashFcn:hash function的函数型别  
  139. //ExtractKey:从节点中取出键值的方法  
  140. //EqualKey:判断键值是否相同  
  141. template <class ValueType,class KeyType,class HashFcn,class ExtractKey,class EqualKey>  
  142. class HashTableClass{  
  143. public:  
  144.     typedef struct __hashtable_node<ValueType> node;//hash table内部链表节点定义  
  145.     //hash table没有提供默认构造函数  
  146.     HashTableClass(size_t n,  
  147.         const HashFcn &hf,  
  148.         const EqualKey &eql,  
  149.         const ExtractKey &ext)  
  150.         :hasher(hf),equals(eql),get_key(ext),num_elements(0)  
  151.     {  
  152.         initialize_buckets(n);  
  153.     }  
  154.     HashTableClass(size_t n,  
  155.         const HashFcn &hf,  
  156.         const EqualKey &eql)  
  157.         :hasher(hf),equals(eql),get_key(ExtractKey()),num_elements(0)  
  158.     {  
  159.         initialize_buckets(n);  
  160.     }  
  161.     HashTableClass(const HashTableClass &ht)  
  162.         :hasher(ht.hasher),equals(ht.equals),get_key(ht.get_key),num_elements(0)  
  163.     {  
  164.         copy_from(&ht);  
  165.     }  
  166.     ~HashTableClass(){clear();};  
  167.     //赋值操作符  
  168.     HashTableClass& operator= (const HashTableClass &ht)  
  169.     {  
  170.         if (&ht != this)  
  171.         {  
  172.             clear();  
  173.             hasher = ht.hasher;  
  174.             equals = ht.equals;  
  175.             get_key = ht.get_key;  
  176.             copy_from(&ht);  
  177.         }  
  178.     }  
  179.     //返回元素个数  
  180.     size_t size(){return num_elements;}  
  181.     //最大元素数目  
  182.     size_t max_size(){return size_t(-1);}  
  183.     //返回bucket vector大小  
  184.     size_t bucket_count(){return buckets.size();}  
  185.     //返回bucket vector可能的最大值  
  186.     size_t max_bucket_count(){return __stl_prime_list[__stl_num_primes - 1];}  
  187.     //插入元素,不允许重复  
  188.     std::pair<node *,bool> insert_unique(const ValueType &obj);  
  189.     //插入元素,允许重复  
  190.     node* insert_equal(const ValueType &obj);  
  191.     //打印所有节点  
  192.     void printAllNodes();  
  193.     //遍历所有buckets  
  194.     void printAllBuckets();  
  195.     //查找某一键值的节点  
  196.     std::pair<node*,bool> find(const KeyType &key);  
  197.     //判断某一值出现的次数  
  198.     size_t count(const KeyType &key);  
  199.     //整体删除  
  200.     void clear();  
  201.     //复制hash表  
  202.     void copy_from(const HashTableClass *ht);  
  203.   
  204. private:  
  205.     std::vector<node*> buckets;//由桶组成的vector  
  206.     size_t num_elements;//总的元素个数  
  207.     HashFcn hasher;  
  208.     ExtractKey get_key;  
  209.     EqualKey equals;  
  210.   
  211.     //节点配置和释放函数  
  212.     node* new_node(const ValueType &obj)  
  213.     {  
  214.         node *tempNode = new node;  
  215.         tempNode->next = NULL;  
  216.         try  
  217.         {  
  218.             construct(&tempNode->val,obj);  
  219.         }  
  220.         catch (...)  
  221.         {  
  222.             delete tempNode;  
  223.             throw;  
  224.             return NULL;  
  225.         }  
  226.         return tempNode;  
  227.     }  
  228.   
  229.     void delete_node(node *n)  
  230.     {  
  231.         destroy(&n->val);  
  232.         delete n;  
  233.     }  
  234.   
  235.     //初始化buckets vector  
  236.     void initialize_buckets(size_t n);  
  237.   
  238.     //返回最接近n并大于等于n的质数  
  239.     size_t next_size(size_t n)const{return __get_next_prime(n);}  
  240.   
  241.     //判断是否需要扩充buckets vector,如有需要则进行扩充  
  242.     void resize(size_t num_elements_hint);  
  243.   
  244.     //判断元素落在哪个bucket  
  245.     //提供两个版本  
  246.     //版本一:只接受实值  
  247.     size_t bkt_num(const ValueType &obj) const{return bkt_num_key(get_key(obj));}  
  248.     //版本二:接受实值和buckets个数  
  249.     size_t bkt_num(const ValueType &obj,size_t n) const {return bkt_num_key(get_key(obj),n);}  
  250.     //版本一:只接受键值  
  251.     size_t bkt_num_key(const KeyType &Key) const{return hasher(Key) % (buckets.size());}  
  252.     //版本二:接受键值和buckets个数  
  253.     size_t bkt_num_key(const KeyType &Key,size_t n) const {return hasher(Key) % n;}  
  254.   
  255.     //在不需要重新分配bucket vector的情况下插入元素,元素不允许重复  
  256.     std::pair<node *,bool> insert_unique_noresize(const ValueType &obj);  
  257.     //在不需要重新分配bucket vector的情况下插入元素,元素不允许重复  
  258.     node* insert_equal_noresize(const ValueType &obj);  
  259. };  
  260.   
  261. template <class ValueType,class KeyType,class HashFcn,class ExtractKey,class EqualKey>  
  262. std::pair<typename HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::node *,bool>   
  263. HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::insert_unique(const ValueType &obj)  
  264. {  
  265.     resize(num_elements + 1);  
  266.   
  267.     return insert_unique_noresize(obj);  
  268. }  
  269.   
  270. template <class ValueType,class KeyType,class HashFcn,class ExtractKey,class EqualKey>  
  271. typename HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::node *  
  272. HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::insert_equal(const ValueType &obj)  
  273. {  
  274.     resize(num_elements + 1);  
  275.   
  276.     return insert_equal_noresize(obj);  
  277. }  
  278.   
  279. template <class ValueType,class KeyType,class HashFcn,class ExtractKey,class EqualKey>  
  280. void HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::printAllNodes()  
  281. {  
  282.     cout << endl;  
  283.     cout << "Current node in hash table : " << endl;  
  284.     for (size_t i = 0;i < buckets.size();++i)  
  285.     {  
  286.         typename HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::node* curNode = buckets[i];  
  287.         while(curNode)  
  288.         {  
  289.             cout << curNode->val << " ";  
  290.             curNode = curNode->next;  
  291.         }  
  292.     }  
  293.     cout << endl;  
  294. }  
  295.   
  296. template <class ValueType,class KeyType,class HashFcn,class ExtractKey,class EqualKey>  
  297. void HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::printAllBuckets()  
  298. {  
  299.     cout << endl;  
  300.     cout << "Current buckets in hash table : " << endl;  
  301.     for (size_t i = 0;i < buckets.size();++i)  
  302.     {  
  303.         typename HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::node* curNode = buckets[i];  
  304.         if(NULL == curNode)  
  305.             cout << "buckets[" << i << "] is empty!" << endl;  
  306.         else  
  307.         {  
  308.             size_t count = 0;  
  309.             while(curNode)  
  310.             {  
  311.                 ++count;  
  312.                 curNode = curNode->next;  
  313.             }  
  314.             cout << "buckets[" << i << "] has " << count << " elements : ";  
  315.             curNode = buckets[i];  
  316.             while(curNode)  
  317.             {  
  318.                 cout << curNode->val << " ";  
  319.                 curNode = curNode->next;  
  320.             }  
  321.             cout << endl;  
  322.         }  
  323.     }  
  324. }  
  325.   
  326. template <class ValueType,class KeyType,class HashFcn,class ExtractKey,class EqualKey>  
  327. std::pair<typename HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::node *,bool>   
  328. HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::find(const KeyType &key)  
  329. {  
  330.     size_t bucket_index = bkt_num_key(key);  
  331.     node*first = buckets[bucket_index];  
  332.     while(first)  
  333.     {  
  334.         if (equals(key,get_key(first->val)))  
  335.         {  
  336.             cout << "find the element " << key << " success" << endl;  
  337.             return std::pair<typename HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::node *,bool>(first,true);  
  338.         }  
  339.         first = first->next;  
  340.     }  
  341.   
  342.     cout << "cannot find the element " << key << endl;  
  343.   
  344.     return std::pair<typename HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::node *,bool>(NULL,false);  
  345. }  
  346.   
  347. template <class ValueType,class KeyType,class HashFcn,class ExtractKey,class EqualKey>  
  348. size_t HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::count(const KeyType &key)  
  349. {  
  350.     size_t bucket_index = bkt_num_key(key);  
  351.     node*first = buckets[bucket_index];  
  352.     size_t num = 0;  
  353.     while(first)  
  354.     {  
  355.         if (equals(key,get_key(first->val)))  
  356.         {  
  357.             ++num;  
  358.         }  
  359.         first = first->next;  
  360.     }  
  361.   
  362.     cout << "The element " << key << " appears " << num << " times" << endl;  
  363.     return num;  
  364. }  
  365.   
  366. template <class ValueType,class KeyType,class HashFcn,class ExtractKey,class EqualKey>  
  367. void HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::clear()  
  368. {  
  369.     for (size_t i = 0;i < buckets.size();++i)  
  370.     {  
  371.         node* first = buckets[i];  
  372.         //删除bucket list中的每个节点  
  373.         while(first)  
  374.         {  
  375.             node *next = first->next;  
  376.             delete_node(first);  
  377.             first = next;  
  378.         }  
  379.         buckets[i] = 0;  
  380.     }  
  381.     //总元素个数置0  
  382.     num_elements = 0;  
  383.   
  384.     //vector并未释放掉空间(自动回收)  
  385. }  
  386.   
  387. template <class ValueType,class KeyType,class HashFcn,class ExtractKey,class EqualKey>  
  388. void HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::copy_from(const HashTableClass *ht)  
  389. {  
  390.     buckets.clear();//清除已有vector  
  391.     //使得bucket vector空间和对方相同  
  392.     buckets.reserve(ht->buckets.size());  
  393.     //插入n个元素,null  
  394.     buckets.insert(buckets.end(),ht->buckets.size(),(typename HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::node *)0);  
  395.   
  396.     for (size_t i = 0;i < ht->buckets.size();++i)  
  397.     {  
  398.         if (const node *cur = ht->buckets[i])  
  399.         {  
  400.             node *tempNode = new_node(cur->val);  
  401.             buckets[i] = tempNode;  
  402.             for (node *next = cur->next;next;next = next->next)  
  403.             {  
  404.                 tempNode->next = new_node(next->val);  
  405.                 tempNode = tempNode->next;  
  406.             }  
  407.         }  
  408.     }  
  409.   
  410.     num_elements = ht->num_elements;  
  411. }  
  412.   
  413. template <class ValueType,class KeyType,class HashFcn,class ExtractKey,class EqualKey>  
  414. void HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::initialize_buckets(size_t n)  
  415. {  
  416.     const size_t n_buckets = next_size(n);  
  417.     buckets.reserve(n_buckets);  
  418.     buckets.insert(buckets.end(),n_buckets,(node*)0);  
  419. }  
  420.   
  421. template <class ValueType,class KeyType,class HashFcn,class ExtractKey,class EqualKey>  
  422. void HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::resize(size_t num_elements_hint)  
  423. {  
  424.     //buckets vector重建与否的标准:  
  425.     //比较新的总元素个数和原buckets vector大小  
  426.     const size_t old_n_vector = buckets.size();  
  427.     //需要重新配置  
  428.     if (num_elements_hint > old_n_vector)  
  429.     {  
  430.         const size_t n = next_size(num_elements_hint);  
  431.         if (n > old_n_vector)//有可能vector已到达最大  
  432.         {  
  433.             vector<node*> tempVec(n,(node *)0);  
  434.             for (size_t bucketIndex = 0;bucketIndex < old_n_vector;++bucketIndex)  
  435.             {  
  436.                 node *first = buckets[bucketIndex];//指向节点对应之串行的起始节点  
  437.                 while(first)  
  438.                 {  
  439.                     //计算节点落在哪一个新的bucket内  
  440.                     size_t new_bucket_index = bkt_num_key(first->val,n);  
  441.                     buckets[bucketIndex] = first->next;  
  442.                     first->next = tempVec[new_bucket_index];  
  443.                     tempVec[new_bucket_index] = first;  
  444.                     first = buckets[bucketIndex];  
  445.                 }  
  446.             }  
  447.             //交换新旧两个bucket vector  
  448.             buckets.swap(tempVec);  
  449.         }  
  450.     }  
  451. }  
  452.   
  453. template <class ValueType,class KeyType,class HashFcn,class ExtractKey,class EqualKey>  
  454. std::pair<typename HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::node *,bool>   
  455. HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::insert_unique_noresize(const ValueType &obj)  
  456. {  
  457.     size_t bucket_index = bkt_num(obj);  
  458.     node *first = buckets[bucket_index];  
  459.     //搜索当前链表  
  460.     for (node *curNode = first;curNode;curNode = curNode->next)  
  461.     {  
  462.         if(equals(get_key(obj),get_key(curNode->val)))  
  463.             return pair<typename HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::node*,bool>(curNode,false);  
  464.     }  
  465.   
  466.     node *tempNode = new_node(obj);  
  467.     tempNode->next = first;  
  468.     buckets[bucket_index] = tempNode;  
  469.   
  470.     ++num_elements;  
  471.   
  472.     return pair<typename HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::node*,bool>(tempNode,true);  
  473. }  
  474.   
  475. template <class ValueType,class KeyType,class HashFcn,class ExtractKey,class EqualKey>  
  476. typename HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::node*  
  477. HashTableClass<ValueType,KeyType,HashFcn,ExtractKey,EqualKey>::insert_equal_noresize(const ValueType &obj)  
  478. {  
  479.     size_t bucket_index = bkt_num(obj);  
  480.     node *first = buckets[bucket_index];  
  481.     for (node *curNode = first;curNode;curNode = curNode->next)  
  482.     {  
  483.         //发现与链表中的某键值相等,马上插入,然后返回  
  484.         if (equals(get_key(obj),get_key(curNode->val)))  
  485.         {  
  486.             node *tempNode = new_node(obj);  
  487.             tempNode->next = curNode->next;  
  488.             curNode->next = tempNode;  
  489.             ++num_elements;  
  490.             return tempNode;  
  491.         }  
  492.     }  
  493.   
  494.     //如果没发现键值相等的元素  
  495.     node *tempNode = new_node(obj);  
  496.     //将其插入链表头部  
  497.     tempNode->next = first;  
  498.     buckets[bucket_index] = tempNode;  
  499.     ++num_elements;  
  500.     return tempNode;  
  501. }  



 


HashTable.cpp:

 

[cpp]  view plain copy print ?
 
  1. #include "HashTable.h"  
  2.   
  3. using namespace std;  
  4.   
  5. int main()  
  6. {  
  7.     HashTableClass<int,int,hash<int>,identity<int>,equal_to<int> > *hashTableObj = new HashTableClass<int,int,hash<int>,identity<int>,equal_to<int> >(50,hash<int>(),equal_to<int>());  
  8.   
  9.     cout << "Hash Table size : " << hashTableObj->size() << endl;  
  10.     cout << "Hash Table bucket count : " << hashTableObj->bucket_count() << endl;  
  11.     cout << "Hash Table max bucket count : " << hashTableObj->max_bucket_count() << endl;  
  12.   
  13.     hashTableObj->insert_unique(59);  
  14.     hashTableObj->insert_unique(63);  
  15.     hashTableObj->insert_unique(108);  
  16.     hashTableObj->insert_unique(2);  
  17.     hashTableObj->insert_unique(53);  
  18.     hashTableObj->insert_unique(55);  
  19.     cout << "Hash Table size : " << hashTableObj->size() << endl;  
  20.     hashTableObj->printAllNodes();  
  21.     hashTableObj->printAllBuckets();  
  22.   
  23.     //继续插入元素,使总元素个数达到54个  
  24.     for(int i = 0;i <= 47;++i)  
  25.         hashTableObj->insert_equal(i);  
  26.     cout << endl;  
  27.     cout << "Hash Table size : " << hashTableObj->size() << endl;  
  28.     cout << "Hash Table bucket count : " << hashTableObj->bucket_count() << endl;  
  29.     hashTableObj->printAllNodes();  
  30.     hashTableObj->printAllBuckets();  
  31.   
  32.     hashTableObj->find(2);  
  33.     hashTableObj->count(2);  
  34.   
  35.     HashTableClass<int,int,hash<int>,identity<int>,equal_to<int> > *hashTableObj2 = new HashTableClass<int,int,hash<int>,identity<int>,equal_to<int> >(20,hash<int>(),equal_to<int>());  
  36.   
  37.     cout << "Hash Table 2 size : " << hashTableObj2->size() << endl;  
  38.     cout << "Hash Table 2 bucket count : " << hashTableObj2->bucket_count() << endl;  
  39.     cout << "Hash Table 2 max bucket count : " << hashTableObj2->max_bucket_count() << endl;  
  40.   
  41.     hashTableObj2->copy_from(hashTableObj);  
  42.     cout << "Hash Table 2 size : " << hashTableObj2->size() << endl;  
  43.     cout << "Hash Table 2 bucket count : " << hashTableObj2->bucket_count() << endl;  
  44.     cout << "Hash Table 2 max bucket count : " << hashTableObj2->max_bucket_count() << endl;  
  45.   
  46.     HashTableClass<int,int,hash<int>,identity<int>,equal_to<int> > hashTableObj3(*hashTableObj2);  
  47.     cout << "Hash Table 3 size : " << hashTableObj3.size() << endl;  
  48.     cout << "Hash Table 3 bucket count : " << hashTableObj3.bucket_count() << endl;  
  49.     cout << "Hash Table 3 max bucket count : " << hashTableObj3.max_bucket_count() << endl;  
  50.   
  51.     HashTableClass<char *,char *,hash<char *>,identity<char*>,eqstr > *hashTableObjString = new HashTableClass<char *,char *,hash<char *>,identity<char*>,eqstr >(20,hash<char *>(),eqstr());  
  52.     hashTableObjString->insert_unique("jun");  
  53.     hashTableObjString->insert_unique("hust");  
  54.     cout << "Hash Table hashTableObjString size : " << hashTableObjString->size() << endl;  
  55.     cout << "Hash Table hashTableObjString bucket count : " << hashTableObjString->bucket_count() << endl;  
  56.     cout << "Hash Table hashTableObjString max bucket count : " << hashTableObjString->max_bucket_count() << endl;  
  57.     hashTableObjString->printAllNodes();  
  58.     //hashTableObjString->printAllBuckets();  
  59.     hashTableObjString->find("juu");  
  60.   
  61.     delete hashTableObj;  
  62.     delete hashTableObj2;  
  63.     delete hashTableObjString;  
  64.   
  65.     return 0;  
  66. }  



 

 

运行结果(VS2008+Win7):

 


转载于:https://www.cnblogs.com/gllxy/p/3402109.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值