Chinaunix首页 | 论坛 | 博客
  • 博客访问: 268897
  • 博文数量: 84
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 927
  • 用 户 组: 普通用户
  • 注册时间: 2015-03-06 23:00
个人简介

growing

文章分类

全部博文(84)

文章存档

2017年(6)

2016年(61)

2015年(17)

我的朋友

分类: C/C++

2016-04-03 16:02:30

为哈希冲突而形成的开链法:

  1. #pragma once
  2. #include <vector>
  3. #include <string>

  4. template<class K,class V>
  5. class HashTableNode
  6. {
  7. public:
  8.     HashTableNode()
  9.     {}
  10.     HashTableNode(const K& key,const V& value)
  11.         :_key(key)
  12.         ,_value(value)
  13.         ,_next(NULL)
  14.     {}
  15.     K _key;
  16.     V _value;
  17.     HashTableNode<K,V>* _next;
  18. };

  19. template<class K>
  20. struct DefaultHashFun
  21. {
  22.     size_t operator()(const K&key)
  23.     {
  24.         return key;
  25.     }
  26. };
  27. template<>
  28. struct DefaultHashFun<string>
  29. {
  30.     static size_t BKDRHash(const char *s)
  31.     {
  32.         unsigned int seed = 131;
  33.         unsigned hash = 0;
  34.         while (*s)
  35.         {
  36.             hash = hash*seed + (*s++);

  37.         }
  38.         return (hash & 0x7FFFFFFF);
  39.     }
  40.     size_t operator()(const string& key)
  41.     {
  42.         return BKDRHash(key.c_str());
  43.     }
  44. };

  45. template<class K,class V,class HashFun = DefaultHashFun<K>>
  46. class HashTableBucket
  47. {
  48.     typedef HashTableNode<K,V> KVNode;
  49. public:
  50.     HashTableBucket()
  51.         :_size(0)
  52.     {}
  53.     HashTableBucket(const size_t size)
  54.         :_size(size)
  55.     {
  56.         _tables.resize(size);
  57.     }
  58.     void Swap(HashTableBucket<K,V,HashFun>& ht)
  59.     {
  60.         _tables.(ht._tables);//注意这里的交换是借助vector,不是系统
  61.         swap(_size,ht._size);
  62.     }
  63.     HashTableBucket(const HashTableBucket<K,V,HashFun> &ht)
  64.         :_size(0)
  65.     {
  66.         HashTableBucket<K,V,HashFun> newTables(ht._tables.size());
  67.         for(size_t i = 0;i <ht._tables.size();++i)
  68.         {
  69.             cur = _tables[i];
  70.             while(cur)
  71.             {
  72.                 newTables.Insert(cur->_key,cur->_value);
  73.                 cur = cur->_next;
  74.             }
  75.         }
  76.         Swap(newTables);
  77.     }
  78.     HashTableBucket<K,V>& operator=(const HashTableBucket<K,V,HashFun> &ht)
  79.     {
  80.         if(this != &ht)
  81.         {
  82.             HashTableBucket<K,V,HashFun> tmp(ht);
  83.             this->Swap(tmp);
  84.         }
  85.         return *this;
  86.     }
  87.     ~HashTableBucket()
  88.     {
  89.         for(size_t i = 0;i < _tables.size();++i)
  90.         {
  91.             KVNode* cur = _tables[i];
  92.             while(cur)
  93.             {
  94.                 KVNode* del = cur;
  95.                 cur = cur->_next;
  96.                 delete del;
  97.             }
  98.             _tables[i] = NULL;
  99.         }
  100.         _size = 0;
  101.     }

  102. public:
  103.     size_t HashFunc(const K&key,size_t capacity)
  104.     {
  105.         HashFun hf;
  106.         return hf(key) % capacity;
  107.     }
  108.     bool Insert(const K& key, const V& value)
  109.     {

  110.         _CheckCapacity();

  111.         size_t index = HashFunc(key,_tables.size());
  112.         KVNode* cur = _tables[index];
  113.         while(cur)
  114.         {
  115.             if(cur->_key == key)
  116.             {
  117.                 return false;
  118.             }
  119.             cur = cur->_next;
  120.         }
  121.         //头插
  122.         KVNode* tmp = new KVNode(key,value);
  123.         tmp->_next = _tables[index];
  124.         _tables[index] = tmp;

  125.         ++_size;
  126.     }
  127.     bool Remove(const K& key)
  128.     {
  129.         size_t index = HashFunc(key,_tables.size());
  130.         KVNode* cur = _tables[index];
  131.         if(cur = NULL)
  132.         {
  133.             return false;
  134.         }
  135.         if(cur->_key == key)//当删除的结点为头时
  136.         {
  137.             _tables[index] = cur->_next;
  138.             delete cur;
  139.             return true;
  140.         }
  141.         else//不为头时
  142.         {
  143.             KVNode*prev = cur;
  144.             cur = cur->_next;
  145.             while(cur)
  146.             {
  147.                 if(cur->_key == key)
  148.                 {
  149.                     prev->_next = cur->_next;
  150.                     delete cur;
  151.                     return true;
  152.                 }
  153.                 prev = cur;
  154.                 cur = cur->_next;
  155.             }
  156.             return false;
  157.         }
  158.     }
  159.     KVNode* Find(const K& key)
  160.     {
  161.         size_t index = HashFunc(key,_tables.size());
  162.         KVNode* cur = _tables[index];
  163.         while(cur)
  164.         {
  165.             if(cur->_key == key)
  166.             {
  167.                 return cur;
  168.             }
  169.             cur = cur->_next;
  170.         }
  171.         return NULL;
  172.     }
  173.     void Print()
  174.     {
  175.         for (int i = 0; i < _tables.size(); ++i)
  176.         {
  177.             cout << "table[" << i << "]->";
  178.             KVNode *cur = _tables[i];
  179.             while (cur)
  180.             {
  181.                 cout << cur->_value << ":" << cur->_value << "->";
  182.                 cur = cur->_next;
  183.             }
  184.             cout << endl;
  185.         }
  186.     }
  187. protected:
  188.     size_t _GetNextPrime(size_t size)
  189.     {
  190.         const int _PrimeSize = 28;
  191.         static const unsigned long _PrimeList[_PrimeSize] =
  192.             {
  193.                 53ul, 97ul, 193ul, 389ul, 769ul,
  194.                 1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
  195.                 49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
  196.                 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
  197.                 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
  198.                 1610612741ul, 3221225473ul, 4294967291ul
  199.             };
  200.             if (size == 0)
  201.             {
  202.                 return _PrimeList[0];
  203.             }
  204.             for (int i = 0; i < _PrimeSize; ++i)
  205.             {
  206.                 if (size == _PrimeList[i])
  207.                 {
  208.                     return _PrimeList[i + 1];
  209.                 }
  210.             }
  211.     }
  212.     void _CheckCapacity()
  213.     {
  214.         size_t newCapacity = _GetNextPrime(_size);
  215.         if(_size == newCapacity)
  216.         {
  217.             return;
  218.         }
  219.         
  220.         vector<KVNode*> newTables;
  221.         newTables.resize(newCapacity);

  222.         for(size_t i = 0;i < _tables.size();++i)
  223.         {
  224.             KVNode* cur = _tables[i];
  225.             while(cur)
  226.             {
  227.                 //取结点
  228.                 KVNode* tmp = cur;
  229.                 cur = cur->_next;
  230.                 //插结点
  231.                 size_t newIndex = HashFunc(tmp->_key,newCapacity);
  232.                 tmp->_next = newTables[newIndex];
  233.                 newTables[newIndex] = tmp;
  234.             }
  235.             _tables[i] = NULL;
  236.         }
  237.         _tables.swap(newTables);
  238.     }
  239. protected:
  240.     vector<HashTableNode<K,V>*> _tables;
  241.     size_t _size;
  242. };


  1. void Test3()//
  2. {
  3.     HashTableBucket<string,string> ht;
  4.     ht.Insert("苹果","apple");
  5.     ht.Insert("香蕉","banana");
  6.     ht.Insert("梨","pea");
  7.     ht.Insert("美女","beauty");
  8. }
  9. int main()
  10. {
  11.     Test3();
  12.     return 0;
  13. }

阅读(1315) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~