HashTable-散列表/哈希表
是根据关键字(key)而直接访问在内存存储位置的数据结构。
-
"code" class=
"cpp">
//HashTable.h
-
#pragma once
-
#include
-
#include <
string>
-
using
namespace
std;
-
enum State
-
{
-
EMPTY,
//空
-
EXITS,
//存在
-
DELETE
//已删除
-
};
-
-
template<
class K, class V>
-
struct
HashTableNode
-
{
-
K _key;
-
V _value;
-
};
-
-
-
-
-
template<
class K>
-
struct _
HashFunc
-
{
-
size_t
operator()(
const K& key,
const
size_t& capacity)
//哈希函数,仿函数
-
{
-
return key / capacity;
-
}
-
-
};
-
template<>
-
struct _HashFunc
//模板特化
-
{
-
private:
-
unsigned
int _BKDRHash(
const
char *str)
//key为字符串时哈希函数
-
{
-
unsigned
int seed =
131;
// 31 131 1313 13131 131313 etc..
-
unsigned
int hash =
0;
-
-
while (*str)
-
{
-
hash = hash * seed + (*str++);
-
}
-
return (hash &
0x7FFFFFFF);
-
}
-
public:
-
size_t
operator()(
const
string& key,
const
size_t& capacity)
//仿函数
-
{
-
-
return _BKDRHash(key.c_str()) % capacity;
-
}
-
-
};
-
template<
class K, class V,class HashFunc=_HashFunc
>
-
class
HashTable
-
{
-
-
typedef HashTableNode
Node;
-
public:
-
HashTable(
size_t capacity =
10)
-
:_tables(
new Node[capacity])
-
, _states(
new State[capacity])
-
, _size(
0)
-
, _capacity(capacity)
-
{}
-
~HashTable()
-
{
-
if (_tables !=
NULL)
-
{
-
delete[] _tables;
-
delete[] _states;
-
}
-
-
}
-
HashTable(
const HashTable
& ht)
-
{
-
HashTable
tmp(ht._capacity);
-
for (
size_t i =
0; i < ht._capacity; i++)
-
{
-
tmp.Insert(ht._tables[i]._key, ht._tables[i]._value);
-
}
-
this->Swap(tmp);
-
}
-
HashTable&
operator=(HashTable
ht)
-
{
-
this->Swap();
-
return *
this;
-
}
-
bool Insert(const K& key, const V& value)
-
{
-
_CheckCapacity();
-
size_t index = HashFunc()(key, _capacity);
-
size_t i =
1;
-
while (_states[index] == EXITS)
//二次探测
-
{
-
if (_tables[index]._key == key)
-
{
-
return
false;
-
}
-
index = index +
2 * i -
1;
-
index %= _capacity;
-
++i;
-
}
-
_tables[index]._key = key;
-
_tables[index]._value = value;
-
_states[index] = EXITS;
-
++_size;
-
return
true;
-
}
-
-
bool Find(const K& key)
-
{
-
size_t index = HashFunc()(key, _capacity);
-
size_t start = index;
-
size_t i =
1;
-
while (_states[index] != EMPTY)
//根据二次探测法查找
-
{
-
if (_tables[index]._key == key)
-
{
-
if (_states[index] != DELETE)
-
return
true;
-
else
-
return
false;
-
}
-
index = index +
2 * i -
1;
-
index %= _capacity;
-
if (start == index)
-
return
false;
-
}
-
return
false;
-
}
-
bool Remove(const K& key)
-
{
-
size_t index = HashFunc()(key, _capacity);
-
size_t start = index;
-
size_t i =
1;
-
while (_states[index] != EMPTY)
//根据二次探测法删除
-
{
-
if (_tables[index]._key == key)
-
{
-
if (_states[index] != DELETE)
-
{
-
_states[index] = DELETE;
-
_size--;
-
return
true;
-
}
-
else
-
return
false;
-
}
-
index = index +
2 * i -
1;
-
index %= _capacity;
-
if (start == index)
-
return
false;
-
}
-
return
false;
-
-
-
}
-
void Print()
-
{
-
for (
size_t i =
0; i < _capacity; i++)
-
{
-
//printf("%d-[%s:%s] \n", _states[i], _tables[i]._key, _tables[i]._value);
-
cout << _states[i] <<
" " << _tables[i]._key <<
" " << _tables[i]._value<<
endl;
-
}
-
}
-
private:
-
void Swap(HashTable
& tmp)
-
{
-
swap(_tables, tmp._tables);
-
swap(_states, tmp._states);
-
swap(_size, tmp._size);
-
swap(_capacity, tmp._capacity);
-
}
-
void _CheckCapacity()
//增容
-
{
-
if (_size *
10 / _capacity ==
6)
-
{
-
HashTable
tmp(_capacity *
2);
-
for (
size_t i =
0; i < _capacity; i++)
-
{
-
if (_states[i] == EXITS)
-
tmp.Insert(_tables[i]._key, _tables[i]._value);
-
}
-
this->Swap(tmp);
-
}
-
}
-
-
private:
-
Node* _tables;
//哈希表
-
State* _states;
//状态表
-
size_t _size;
-
size_t _capacity;
-
};
-
"1711228" snippet_file_name=
"blog_20160608_3_3809584" name=
"code"
class=
"cpp">
//test.cpp
-
#include
-
#include "HashTable.h"
-
void testInt()
-
{
-
HashTable<int, int> table(10);
-
table.Insert(
89,
89);
-
table.Insert(
18,
18);
-
table.Insert(
49,
49);
-
table.Insert(
58,
58);
-
table.Insert(
9,
9);
-
//table.Insert(45, 45);
-
//table.Insert(2, 2);
-
table.Print();
-
HashTable<int, int> table1(table);
-
table1.Print();
-
bool ret = table.Find(
9);
-
cout << endl << ret << endl;
-
table.Remove(
9);
-
table.Print();
-
-
}
-
void TestString()
-
{
-
HashTable<string, string> table(10);
-
table.Insert(
"dict",
"字典");
-
table.Insert(
"hash",
"哈希");
-
table.Insert(
"function",
"函数");
-
table.Insert(
"abcd",
"函数");
-
table.Insert(
"dcba",
"函数");
-
-
table.Print();
-
bool ret = table.Find(
"function");
-
cout << endl << ret << endl;
-
table.Remove(
"hash");
-
table.Print();
-
}
-
int main()
-
{
-
//testInt();
-
TestString();
-
getchar();
-
return
0;
-
}