【DS】哈希表实现

来源:互联网 发布:名师讲课软件 编辑:程序博客网 时间:2024/06/06 00:07

哈希表的介绍和扩展请查看这篇文章:http://blog.csdn.net/always__/article/details/51584446


基于线性探测,二次探测的哈希表结构,实现字典查询。

代码如下:

#pragma once#include<iostream>#include<string>using namespace std;////命名空间First--线性探测法//namespace First//{////enum State//{//EMPTY,//DELETE,//EXIST,//};////template<class T>//class HashTable//{//public://HashTable(size_t capacity = 10)//:_tables(new T[capacity]),//_states(new State[capacity]),//_size(0),//_capacity(capacity)//{//for (size_t i = 0;i < _capacity;++i)//{//_states[i] = EMPTY;//}//}//~HashTable()//{//if (_tables)//{//delete []_tables;//delete []_states;//}//}////拷贝构造函数//HashTable(const HashTable<T>& ht)//:_tables(NULL)//, _status(NULL)//,_size(0)//,_capacity(0)//{//HashTable<K> newTables(ht._capacity);//for (size_t i = 0; i < ht._capacity; ++i)//{//if (ht._status[i] == EXITS)//{//newTables.Insert(ht._tables[i]);//}//}////this->Swap(newTables);//}//////重载赋值运算符//HashTable<T>& operator=(HashTable<T> ht)//{//this->Swap(ht);////return *this;//}//bool Insert(const T& key)//{//_CheckCapacity();/////*if (_size == _capacity)//{//cout << "HashTable is Full" << endl;//return false;//}*/////size_t index = HashFunc(key);////线性探测////while (_states[index] == EXIST)//{//if (_tables[index] == key)//{//return false;//}////++index;//if (index == _capacity)//{//index = 0;//}//}//_tables[index] = key;//_states[index] = EXIST;//_size++;//}//////////////改进版////bool Insert(const T& key)////{////_CheckCapacity();///////*if (_size == _capacity)////{////cout << "HashTable is Full" << endl;////return false;////}*///////size_t index = HashFunc0(key);//////线性探测//////while (_states[index] == EXIST)////{////if (_tables[index] == key)////{////return false;////}//////index = _HashFunci(index, i++);////index %= _capacity;////}////_tables[index] = key;////_states[index] = EXIST;////_size++;////}////////////////bool Find(const T& key)//{//size_t index = HashFunc(key);//size_t start = index;//bool find = false;////while (_states[index] != EMPTY)//{//if (_tables[index] == key )//{//if (_states[index] != DELETE)//{//return true;//}//return false;//}////++index;//if (index == _capacity)//{//index = 0;//}//if (index == start)//{//return false;//}//}//return false;//}////bool Remove(const T& key)//{//size_t index = HashFunc(key);//size_t start = index;////while (_states[index] != EMPTY)//{//if (_tables[index] == key)//{//_states[index] = DELETE;//_size--;//return true;//}////++index;//if (index == _capacity)//{//index = 0;//}//if (index == start)//{//return false;//}//}//}//void Print()//{//for (size_t i = 0;i < _capacity;++i)//{//printf("[%d : %d]--\n", _states[i], _tables[i]);//}//cout << endl;//}//protected://void Swap(HashTable<T> &tmp)//{//swap(_tables, tmp._tables);//swap(_states, tmp._states);//swap(_size, tmp._size);//swap(_capacity, tmp._capacity);//}//size_t HashFunc(const T& key)//{//return key%_capacity;//}////void _CheckCapacity()//{//if (_size * 10 / _capacity == 7)//{//HashTable<T> tmp(2 * _capacity);//for (size_t i = 0;i < _capacity;++i)//{//if (_states[i] == EXIST)//{//tmp.Insert(_tables[i]);//}//}//this->Swap(tmp);//}//}//////protected://T* _tables;//哈希表//State* _states;    //状态表//size_t _size;//大小//size_t _capacity;//};//}////////命名空间Second--闭散列的二次探测//namespace Second//{//enum State//{//EMPTY,//DELETE,//EXIST,//};////template<class T>//class HashTable//{//public://HashTable(size_t capacity = 10)//:_tables(new T[capacity]),//_states(new State[capacity]),//_size(0),//_capacity(capacity)//{//for (size_t i = 0;i < _capacity;++i)//{//_states[i] = EMPTY;//}//}//~HashTable()//{//if (_tables)//{//delete[]_tables;//delete[]_states;//}//}//bool Insert(const T& key)//{//_CheckCapacity();//size_t index = HashFunc(key);//int i = 1;//while (_states[index] ==EXIST)//{//if (_tables[index] == key)//{//return false;//}////index = HashFunc(key) + i*i;//index %= _capacity;//++i;////}////_tables[index] = key;//_states[index] = EXIST;//_size++;//}//bool Find(const T& key)//{////}////bool Remove(const T& key)//{////}//size_t HashFunc(const T& key)//{//return key%_capacity;//}//void Print()//{//for (size_t i = 0;i < _capacity;++i)//{//printf("[%d : %d]--", _states[i], _tables[i]);//}//cout << endl;//}////void _CheckCapacity()//{//if (_size * 10 / _capacity == 7)//{////重新建表////HashTable<T> tmp(2 * _capacity);//for (size_t i = 0;i < _capacity;++i)//{//if (_states[i] == EXIST)//{//tmp.Insert(_tables[i]);//}//}//this->Swap(tmp);//}//}//void Swap(HashTable<T> &tmp)//{//swap(_tables, tmp._tables);//swap(_states, tmp._states);//swap(_size, tmp._size);//swap(_capacity, tmp._capacity);//}//protected://T* _tables;//哈希表//State* _states;    //状态表//size_t _size;//大小//size_t _capacity;//};//}//明名空间3--哈希表的key/value形式的二次探测namespace Third{enum State{EMPTY,DELETE,EXIST,};template<class K, class V>struct HashTableNode{HashTableNode(){}HashTableNode(const K& key, const V& value):_key(key),_value(value){}K _key;V _value;};static size_t StringHash(const char* str){size_t sum = 0;while (*str != '\0'){sum += *str;str++;}return sum;}template<class K>struct __HashFunc{size_t operator()(const K& key){return key;}};//模板特化template<>struct __HashFunc<string>{size_t operator()(const string& str){return StringHash(str.c_str());}};template<class K, class V, class HashFunction = __HashFunc<K>>class HashTable{typedef HashTableNode<K, V> Node;public:HashTable():_tables(NULL), _size(0), _capacity(0), _status(0){}HashTable(size_t capacity = 10):_tables(new Node[capacity]),_states(new State[capacity]),_size(0),_capacity(capacity){for (size_t i = 0;i < capacity;++i){_states[i] = EMPTY;}}~HashTable(){if (_tables){delete[]_tables;delete[]_states;}}bool Insert(const K& key, const V& value){_CheckCapacity();size_t index = HashFunc(key);int i = 1;//基于二次探测while (_states[index] == EXIST){if (_tables[index]._key == key){return false;}index = HashFunc(key) + i*i;index %= _capacity;++i;}_tables[index] = Node(key, value);_states[index] = EXIST;++_size;return true;}Node* Find(const K& key){size_t index = HashFunc(key);size_t start = index;int i = 1;while (_states[index] != EMPTY){if (_tables[index]._key == key){if (_states[index] == EXIST){return &(_tables[index]);}return NULL;}index += i*i;if (index >=_capacity){index %= _capacity;}if (index == start){break;}}return NULL;}size_t HashFunc(const K& key){HashFunction hf;return (hf(key)) % _capacity;}void Print(){for (size_t i = 0;i < _capacity;++i){cout << "【" << _tables[i]._key<<" --- ";cout << _tables[i]._value << "】";}cout << endl;}protected:void _CheckCapacity(){if (_size < _capacity){return;}HashTable<K,V,HashFunction> newTable(2 * _capacity);for (size_t index = 0;index < _capacity;++index){if (_states[index] == EXIST){newTable._tables[index] = _tables[index];newTable._states[index] = EXIST;newTable._size = _size;}}this->Swap(newTable);}void Swap(HashTable<K, V, HashFunction>& other){swap(_tables, other._tables);swap(_states, other._states);swap(_size, other._size);swap(_capacity, other._capacity);}protected:Node* _tables;State* _states;size_t _size;size_t _capacity;};void TestHashTable(){HashTable<string, string> ht1(10);ht1.Insert("dict", "字典");ht1.Insert("hash", "哈希");ht1.Insert("function", "函数");ht1.Insert("lauyang", "刘阳阳");HashTableNode<string, string>* ret = ht1.Find("lauyg");if (ret){cout << "hash的中文是: " << ret->_value << endl;}else{cout << "not exist" << endl;}}}

哈希桶实现字典查询:

#pragma once#include <vector>#include<iostream>using namespace std;//哈希桶key-value结构namespace BUCKET{template<class K,class V>struct HashTableNode{K _key;V _value;HashTableNode<K, V>* _next;HashTableNode(const K& key, const V& value):_key(key),_value(value),_next(NULL){}};template<class K,class V>class HashTable{typedef HashTableNode<K, V> Node;typedef HashTable<K, V> Table;public:HashTable():_size(0){}HashTable(size_t capacity)//capacity最好是素数,这样可以减少哈希冲突。:_size(0){ _tables.resize(_GetNextPrime(capacity));//确保开辟素数大小空间}~HashTable(){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;}_tables[i] = NULL;}_size = 0;}HashTable(const Table& other):_size(0){Table newTables(other._tables.size());newTables._size = other._size;for (size_t i = 0;i < other._tables.size();++i){Node* cur = other._tables[i];Node*& head = newTables._tables[i];while (cur){//newTables.Insert(cur->_key, cur->_value);Node* tmp= new Node(cur->_key, cur->_value);tmp->_next = head;head = tmp;cur = cur->_next;}}this->Swap(newTables);}/*Table& operator=(Table t){_tables.swap(t);swap(_size, t._size);return _tables;}*/Table& operator=(Table& t){if (this != &t){Table tmp(t);_tables.swap(t);swap(_size, t._size);}return _tables;}bool Insert(const K& key, const V& value){size_t index = _HashFunc(key,_tables.size());//检查是否存在Node* cur=_tables[index];while (cur){if (cur->_key ==key){return false;}cur = cur->_next;}//头插法Node* tmp = new Node(key, value);tmp->_next = _tables[index];_tables[index] = tmp;++_size;return true;}Node* Find(const K& key){size_t index = _HashFunc(key, _tables.size());Node* cur = _tables[index];while (cur){if (cur->_key == key){return cur;}cur = cur->_next;}return NULL;}bool Remove(const K& key){size_t index = _HashFunc(key, _tables.size());Node* cur = _tables[index];if (cur == NULL){return false;}if (cur->_key == key){_tables[index] = cur->_next;delete cur;return true;}else{Node* prev = cur;cur = cur->_next;while (cur){if (cur->_key==key){prev->_next = cur->_next;delete cur;return true;}prev = cur;cur = cur->_next;}return false;}}void Print(){for (size_t i = 0; i < _tables.size(); ++i){printf("tables[%d]->", i);Node* cur =_tables[i];while (cur){cout << "[" << cur->_key << ":" << cur->_value << "]" << "->";cur = cur->_next;}cout << "NULL" << endl;}cout << endl;}protected:size_t _GetNextPrime(size_t size){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 (_PrimeList[i] > size){return _PrimeList[i];}}return _PrimeList[_PrimeSize - 1];}size_t _HashFunc(const K& key,size_t capacity){return key % capacity;}void _CheckCapacity(){//负载值为1时增容if (_size == _tables.size()){size_t nextPrime = _GetNextPrime(_size);vector<Node*> newTables;newTables.resize(nextPrime);for (size_t i = 0;i < _tables.size();++i){Node* cur = _tables[i];while (cur){Node* tmp = cur;cur = cur->_next;//头插size_t index = _HashFunc(tmp->_key, newTables.size());tmp->_next = newTables[index];newTables[index] = tmp;}_tables[i] = NULL;}_tables.swap(newTables);}}void Swap(Table &other){_tables.swap(other._tables);swap(_size,other._size);}private:vector<HashTableNode<K, V>*> _tables;size_t _size;//Node底下挂多少数据};void TestHashBucketTable(){HashTable<int, int> ht(20);ht.Insert(1, 14);ht.Insert(2, 12);ht.Insert(3, 21);ht.Insert(4, 11);ht.Print();//删除remove/*ht.Remove(1);ht.Print();*///测试拷贝构造HashTable<int, int> other(ht);other.Print();//find函数/*HashTableNode<int,int>* ret = ht.Find(1);if (ret){cout<<"the key is exist: "<<ret->_key<<" "<<ret->_value<<endl;}else{cout<<"it is not exist"<<endl;}*/}}//哈希桶,基于key-value+仿函数的实现namespace HASHBUCKET{template<class K, class V>struct HashTableNode{K _key;V _value;HashTableNode<K, V>* _next;HashTableNode(const K& key, const V& value):_key(key),_value(value),_next(NULL){}};template<class K>struct DefaultHashFunc{size_t operator()(const K& key){return key;}};template<>struct DefaultHashFunc<string>{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);}size_t operator() (const string& key){return BKDRHash(key.c_str());}};template<class K, class V,class HashFunc=DefaultHashFunc<K>>class HashTable{typedef HashTableNode<K,V> Node;typedef HashTable<K,V,HashFunc> Table;public:HashTable():_size(0){}HashTable(size_t capacity)//capacity最好是素数,这样可以减少哈希冲突。:_size(0){_tables.resize(_GetNextPrime(capacity));//确保开辟素数大小空间}~HashTable(){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;}_tables[i] = NULL;}_size = 0;}HashTable(const Table& other):_size(0){Table newTables(other._tables.size());newTables._size = other._size;for (size_t i = 0;i < other._tables.size();++i){Node* cur = other._tables[i];Node*& head = newTables._tables[i];while (cur){//newTables.Insert(cur->_key, cur->_value);Node* tmp = new Node(cur->_key, cur->_value);tmp->_next = head;head = tmp;cur = cur->_next;}}this->Swap(newTables);}/*Table& operator=(Table t){_tables.swap(t);swap(_size, t._size);return _tables;}*/Table& operator=(Table& t){if (this != &t){Table tmp(t);_tables.swap(t);swap(_size, t._size);}return _tables;}bool Insert(const K& key, const V& value){size_t index = _HashFunc(key, _tables.size());//检查是否存在Node* cur = _tables[index];while (cur){if (cur->_key == key){return false;}cur = cur->_next;}//头插法Node* tmp = new Node(key, value);tmp->_next = _tables[index];_tables[index] = tmp;++_size;return true;}Node* Find(const K& key){size_t index = _HashFunc(key, _tables.size());Node* cur = _tables[index];while (cur){if (cur->_key == key){return cur;}cur = cur->_next;}return NULL;}bool Remove(const K& key){size_t index = _HashFunc(key, _tables.size());Node* cur = _tables[index];if (cur == NULL){return false;}if (cur->_key == key){_tables[index] = cur->_next;delete cur;return true;}else{Node* prev = cur;cur = cur->_next;while (cur){if (cur->_key == key){prev->_next = cur->_next;delete cur;return true;}prev = cur;cur = cur->_next;}return false;}}void Print(){for (size_t i = 0; i < _tables.size(); ++i){printf("tables[%d]->", i);Node* cur = _tables[i];while (cur){cout << "[" << cur->_key << ":" << cur->_value << "]" << "->";cur = cur->_next;}cout << "NULL" << endl;}cout << endl;}protected:size_t _GetNextPrime(size_t size){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 (_PrimeList[i] > size){return _PrimeList[i];}}return _PrimeList[_PrimeSize - 1];}size_t _HashFunc(const K& key, size_t capacity){return HashFunc()(key) % capacity;}void _CheckCapacity(){//负载值为1时增容if (_size == _tables.size()){size_t nextPrime = _GetNextPrime(_size);vector<Node*> newTables;newTables.resize(nextPrime);for (size_t i = 0;i < _tables.size();++i){Node* cur = _tables[i];while (cur){Node* tmp = cur;cur = cur->_next;//头插size_t index = _HashFunc(tmp->_key, newTables.size());tmp->_next = newTables[index];newTables[index] = tmp;}_tables[i] = NULL;}_tables.swap(newTables);}}void Swap(Table &other){_tables.swap(other._tables);swap(_size, other._size);}private:vector<HashTableNode<K, V>*> _tables;size_t _size;//Node底下挂多少数据};void TestHashBucketTable(){HashTable<string, string> dict(10);dict.Insert("字典", "dict");dict.Insert("插入", "Insert");dict.Insert("删除", "Remove");dict.Insert("查找", "Find,Search");dict.Print();//删除remove/*dict.Remove("字典");dict.Print();*///测试拷贝构造//HashTable<int, int> other(ht);//other.Print();//find函数HashTableNode<string,string>* ret = dict.Find("插入");if (ret){cout<<"the key is exist: "<<ret->_key<<" : "<<ret->_value<<endl;}else{cout<<"it is not exist"<<endl;}}}

0 0
原创粉丝点击