哈希表的构造之开链法
来源:互联网 发布:网络信息许可证 编辑:程序博客网 时间:2024/05/02 00:47
前面总体介绍了一下有关哈希算法(哈希表如何构造,怎样减少哈希冲突等):
http://blog.csdn.net/qq_29503203/article/details/52992810
今天主要来实现一下哈希表的构造之开链法,这种方法可以将负载因子延伸到1,即_size==_tables.size(),这样对空间的利用率提高了许多,首先来看一下它的原理:
下面是代码实现:
template<class K>struct GetKType{size_t operator()(const K& key){return key;}};template<>struct GetKType<string> //模板的特化{//字符串哈希算法(将字符串转为整型)static size_t BKDRHash(const char* str) //BKDRHash算法{unsigned int seed= 131;// 31 131 1313 13131 131313unsigned int hash= 0;while(*str){hash=hash*seed+(*str++);}return(hash& 0x7FFFFFFF);}size_t operator()(const string& str){return BKDRHash(str.c_str());}};template<class K,class V>struct HashListNode{HashListNode<K,V>* _next;K _key;V _value;HashListNode(const K& key,const V& value):_key(key),_value(value),_next(NULL){}};template<class K,class V,class HashFunc=GetKType<K> >class HashList{typedef HashListNode<K,V> Node;public:HashList():_size(0){_tables.resize(_GetNextPrime(0));}~HashList(){if(_tables.empty())return;for(size_t i=0;i<_tables.size();++i){Node* cur=_tables[i];while(cur){Node* tmp=cur;cur=cur->_next;delete tmp;tmp=NULL;}}_size=0;_tables.clear();}bool Insert(const K& key,const V& value){_CheckSize();size_t index=_HashFunc(key,_tables.size());//先检查该元素是否已在表中了Node* cur=_tables[index];while(cur){if(cur->_key==key)return false;cur=cur->_next;}//采取头插Node* NewNode=new Node(key,value);NewNode->_next=_tables[index];_tables[index]=NewNode;++_size;}bool Find(const K& key){size_t index=_HashFunc(key,_tables.size());Node* cur=_tables[index]; //先定位到在表中哪个位置while(cur){if(cur->_key==key)return true;elsecur=cur->_next;}return false;}bool Remove(const K& key){if(_tables.empty())return false;size_t index=_HashFunc(key,_tables.size());Node* cur=_tables[index];Node* prev=NULL;while(cur){//1.删除头结点//2.删除中间节点及尾节点if(cur->_key==key){if(prev==NULL){_tables[index]=cur->_next;}else{prev->_next=cur->_next;}delete cur;cur=NULL;--_size;return true;}prev=cur;cur=cur->_next;}return false;}void Print() { if (_size == 0) return; for (size_t i = 0; i < _tables.size(); ++i) { Node* cur = _tables[i]; //cout << "_tables[" << i << "]" << "->";printf("_tables[%d]:",i); while (cur) { cout << cur->_key << "->"; cur = cur->_next; } cout << "NULL" << endl; } }protected:void _Swap(HashList<K,V,HashFunc>& hl){std::swap(hl._tables,_tables);std::swap(hl._size,_size);}size_t _HashFunc(const K& key,size_t size){HashFunc hf;return hf(key)%size;}size_t _GetNextPrime(size_t num){const int _PrimeSize= 28; static const unsigned long _PrimeList[_PrimeSize] = {53ul, 97ul, 193ul, 389ul, 769ul,1543ul, 3079ul, 6151ul, 12289ul, 24593ul,49157ul, 98317ul, 196613ul, 393241ul,786433ul,1572869ul, 3145739ul, 6291469ul, 12582917ul,25165843ul,50331653ul, 100663319ul, 201326611ul, 402653189ul,805306457ul,1610612741ul, 3221225473ul, 4294967291ul };for(size_t i=0;i<_PrimeSize;++i){if(num < _PrimeList[i]){return _PrimeList[i];}return _PrimeList[i-1];}return _PrimeList[_PrimeSize-1]; //如果size大于或等于素数表中数据,就返回表中最大数 }void _CheckSize(){if(_size >= _tables.size()) //负载因子为1就开始扩容{size_t NewSize=_GetNextPrime(_tables.size());//通过原表中的数据算出在新表中的位置vector<Node*> newTables; //出了这个作用域就销毁newTables.resize(NewSize);for(size_t i=0;i<_tables.size();++i){Node* cur=_tables[i];while(cur){Node* tmp=cur->_next;cur=cur->_next;size_t index=_HashFunc(tmp->_key,newTables.size());newTables[index]=tmp; }}_tables.swap(newTables);}}protected:vector<Node*> _tables;size_t _size;};
0 0
- 哈希表的构造之开链法
- 哈希表的构造之线性探测法
- 构造哈希表之开链法(哈希桶)
- C++对象模型之默认构造函数的构造操作
- C++对象模型之复制构造函数的构造操作
- 构造函数之二:构造函数常见的使用方式
- 类的成员之三:构造器(构造方法)
- C++对象模型之默认构造函数的构造操作,拷贝构造函数同
- 构造方法的访问级别之private
- ”extends“之令人恶心的构造器
- C++类的定义之构造函数
- 构造方法的访问级别之private
- go语言之初始化的构造函数
- Html5之Svg对象的构造方法
- 类的构造和初始化之二
- C++之构造函数的种类
- 构造方法的访问级别之private
- lua学习之表的构造
- 9. Palindrome Number
- 在5个数中找最大的数,并把他放入MAX单元
- sizeof(数组名)和sizeof(指针)
- pycharm快捷键
- 写好Java代码的30条经验总结
- 哈希表的构造之开链法
- Introduction to Articial Intelligence
- 使用pyqt4开发GUI程序的问题总结
- JavaScript快速上手之5:事件
- Unity3D自学笔记——UGUI背包系统(六)角色换装及属性动态改变
- MediaMetadataRetriever类取得媒体文件信息
- Android事件处理(二)——View的dispatchTouchEvent 函数源码详解
- C++中的继承关系
- 输出10000以内的回文数