哈希表线性探测&二次探测
来源:互联网 发布: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;}}
阅读全文
2 0
- 哈希表线性探测&二次探测
- HashTable哈希表/散列表(线性探测和二次探测)
- 哈希表,二次探测再散列
- Java实现hash表,线性探测,二次探测,再哈希法,链表法
- 哈希表---线性探测法
- 哈希表线性探测再散列
- 哈希表-线性探测
- 线性探测再散列和平方探测再散列(二次探测再散列)算法
- 哈希表(线性探测再散列)
- 线性探测法构建哈希表
- 实验 哈希表线性探测再散列
- 哈希表KV形式的二次探测
- 构造哈希表之二次探测法
- HashTable二次探测
- 哈希表 除数余留 + 链地址 && 线性探测 && 平方探测
- 哈希冲突的处理【闭散列方法-线性探测和二次探测】
- 线性探测再散列解决冲突的哈希表
- 使用线性探测法构造哈希表
- git学习四:eclipse使用git提交项目
- Git 解除上传文件大小的限制
- struts2+hibernate+spring注解版框架搭建以及简单测试(方便脑补)
- 反汇编引擎diStorm3
- Fragment与Android架构
- 哈希表线性探测&二次探测
- ISE软件及相关安装
- Chrome浏览器F12开发者工具的几个小技巧总结
- git使用
- git学习三:git常用命令
- tomcat发现一个奇怪的问题,如我在本地tomcat发布了一个工程testProject,输入127.0.0.1:8080/testProject登录了,但是输入:本机ip地址:8080/testP
- hplsql安装说明
- 全志R116平台tinav2.1系统下的录音播音测试(分色排版)
- 图解HTTP学习