您的位置:首页 > 其它

哈希冲突之开链法

2016-03-17 15:09 429 查看
哈希碰撞/哈希冲突:不同的Key值经过哈希函数Hash(Key)处理以后可能产生相同的值哈希地址,我们称这种情况为哈希冲突。



#include<iostream>
#include<vector>
#include<string>
using namespace std;
template<class K,class V>
struct Node
{
K _key;
V _value;
Node*_next;
Node(const K& key, const V& value)
:_key(key)
, _value(value)
, _next(NULL)
{}
};
template<class T>
struct Hasher
{
size_t operator() (const T& key)
{
return key;
}
};

template<>
struct Hasher<string>
{
size_t operator() (const string& s)
{
const char* str = s.c_str();

unsigned int seed = 131; // 31 131 1313 13131 131313
unsigned int hash = 0;
while (*str)
{
hash = hash * seed + (*str++);
}

return (hash & 0x7FFFFFFF);
}
};

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
};
template<class K, class V, class HashFunc = Hasher<K>>
class HashTable
{
public:
HashTable(size_t capacity)
{
_size = 0;
_table.reserve(capacity);
_table.assign(capacity, NULL);
}
void Insert(const K& key, const V& value)//放入数据
{
ExpandCapacity();

int pos = _HashFunc(key, _table.size());
Node<K,V>*begin = _table[pos];
while (begin != NULL)
{
if (begin->_key == key)
{
return;
}
begin = begin->_next;
}
Node<K,V>*tmp = new Node<K,V>(key, value);
tmp->_next = _table[pos];
_table[pos] = tmp;
++_size;
}
void Delete(const int&key)//删除结点
{
size_t pos = (size_t)key % (size_t)_table.capacity();
Node*begin = _table[pos];
Node*prev = NULL;
while (begin)
{
if (begin->_key == key)
{
if (begin == _table[pos])
{
_table[pos] = _table[pos]->_next;
}
else
{
prev->_next = begin->_next;
}
delete begin;
return;
}
prev = begin;
begin = begin->_next;
}
}
void Print()
{
for (int i = 24; i <(int) _table.capacity(); i++)
{
Node<K,V>*begin = _table[i];
while (begin != NULL)
{
printf("pos[%d]:", i);
cout << "(" << begin->_key <<","<< begin->_value<<")";
cout << "->";
begin = begin->_next;
}
cout <<"NULL"<< endl;
}
}

protected:
void ExpandCapacity()//实现扩容
{
if (_size >= (size_t)_table.capacity())
{
int NewCapacity = CapacityNum(_size);
vector<Node<K,V> *>tmp;
tmp.reserve(NewCapacity);
tmp.assign(NewCapacity, NULL);
for (size_t i = 0; i < (size_t)_table.capacity(); i++)
{
while (_table[i] != NULL)
{
//摘节点
Node<K,V>* head = _table[i];
_table[i] = _table[i]->_next;

//放节点
int pos = _HashFunc((head->_key),NewCapacity);
head->_next = tmp[pos];
tmp[pos] = head;
}
}
_table.swap(tmp);
}
}
size_t CapacityNum(size_t num) //得到应该扩展到的容量值
{
for (int i = 0; i < _PrimeSize; i++)
{
if (_PrimeList[i]>num)
{
return _PrimeList[i];
}
}
return _PrimeList[_PrimeSize - 1];
}

int _HashFunc(const K& key, size_t capacity)
{
HashFunc hashFunc; // operator()
return hashFunc(key) % _table.capacity();

}
private:
vector<Node<K,V>*>_table;
size_t _size;
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: