您的位置:首页 > 其它

【DS】哈希表实现

2016-06-04 16:28 218 查看
哈希表的介绍和扩展请查看这篇文章: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 131313
unsigned 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;
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: