哈希表线性探测&二次探测

来源:互联网 发布:c语音递归算法1加到100 编辑:程序博客网 时间:2024/06/10 15:12

在代码中实现了哈希表中任意类型都可以存放,即哈希函数要可扩展以及哈希表动态增容的功能。

贴上代码:

#include<iostream>#include<vector>using namespace std;template<class K>//特化 class _HashFun { public: size_t operator()(K key) { return key; } }; template<> class _HashFun<string> { public: size_t operator()(const char* str) { return BKDRHash(str); } private: static size_t BKDRHash(const char * str)  {unsigned int seed = 131; // 31 131 1313 13131 131313unsigned int hash = 0;while (*str ){hash = hash * seed + (*str++);}return (hash & 0x7FFFFFFF);  } };enum State //状态标志{EXIST,EMPTY,DELETE,};template<class K, class V>struct HashElem //哈希元素{HashElem():_s(EMPTY){}pair<K, V> _kv;State _s;};template<class K, class V, class HashFunc = _HashFun<K>, bool Isline = true>class HashTable //哈希表{public:HashTable(size_t size = 12):_size(0){_table.resize(size);}bool Insert(const K& key, const V& value){_CheckTable();//如果表满if(_size == _table.size())return false;        size_t hashAddr = _HashFunc(key);//找哈希地址size_t H0 = hashAddr;size_t i = 1; while(EXIST == _table[hashAddr]._s)//冲突{if(key == _table[hashAddr]._kv.first)//只插入唯一值return false;if(Isline){hashAddr =  HashFunc1(H0);}else{hashAddr =  HashFunc2(H0, i);}i++;    //hashAddr++;//线性探测//if(hashAddr == _table.size())//找到最后一个再从头开始//hashAddr = 0;}//插入_table[hashAddr]._kv.first = key;_table[hashAddr]._kv.second = value;_table[hashAddr]._s = EXIST;_size++;return true;}pair<HashElem<K,V>*, bool> Find(const K& key)//查找值为key的元素{size_t hashAddr = _HashFunc(key);    size_t H0 = hashAddr;size_t i = 1;while(EMPTY != _table[hashAddr]._s){if(_table[hashAddr]._kv.first == key){if(_table[hashAddr]._s == EXIST)return make_pair(&_table[hashAddr], true);else//DELETEreturn make_pair((HashElem<K, V>*)NULL, false);//这里需要强转,否则编译器可能将NULL当成0}if(Isline){hashAddr =  HashFunc1(H0);}else{hashAddr =  HashFunc2(H0, i);}i++;//hashAddr++;//线性探测//if(hashAddr == _table.size())//hashAddr = 0;}return make_pair((HashElem<K,V>*)NULL,false);}bool Remove(const K& key)//删除{pair<HashElem<K, V>*, bool> pos = Find(key);if(pos.second){pos.first->_s = DELETE;_size--;return true;}return false;}private:size_t _HashFunc(const K& key){return HashFunc()(key) % 10/*_table.size()-1*/;}// 线性探测处理函数size_t HashFunc1(size_t hashAddr){hashAddr++;if(hashAddr == _table.size())hashAddr = 0;return hashAddr;}// 二次探测处理函数size_t HashFunc2(size_t hashAddr, size_t i){if(hashAddr >= _table.size())hashAddr = 0;return hashAddr+2*i+1;}void Swap(HashTable<K,V>& ht){_table.swap(ht._table);//两个容器交换不创建临时对象 swap(_size, ht._size);}void _CheckTable(){if(_size*10 / _table.size() >= 7){size_t newsize = _table.size()*2;//乘2可能会越界//newsize = GetNextPrime(newsize);//交换法 销毁原来的空间HashTable<K, V> ht(newsize);for(int idx = 0;idx <= _table.size();idx++){if(_table[idx]._s == EXIST)ht.Insert(_table[idx]._kv.first, _table[idx]._kv.second);}Swap(ht);}}vector<HashElem<K, V>> _table;size_t _size;//有效元素的个数};void FunTest(){int a[] = {11,25,37,14,36,49,57};HashTable<int, int> ht;for(int idx = 0; idx <sizeof(a)/sizeof(a[0]); idx++)ht.Insert(a[idx], idx);pair<HashElem<int, int>*, bool> pos = ht.Find(25);if(pos.second){cout<<pos.first->_kv.first<<endl;}else{cout<<"没有找到该元素"<<endl;}ht.Remove(25);pair<HashElem<int, int>*, bool> pos1 = ht.Find(25);if(pos1.second){cout<<pos1.first->_kv.first<<endl;}else{cout<<"没有找到该元素"<<endl;}}


原创粉丝点击