HashTable.h
#pragma once
#include <functional>
#include <stdexcept>
template<typename Key,typename Value,typename Hash = std::hash<Key>>
class HashTable
{
private:
class List
{
public:
class Node
{
public:
Node* next = nullptr;
Key key;
Value value;
public:
Node(const Key& k, const Value& v) :key(k), value(v)
{
}
~Node()
{
if (next != nullptr)
delete next;
}
};
Node* head = nullptr;
public:
/****************************************************
函数名称: put
函数说明: 存储key-value并判断是否更新kvcount
返回值: bool
****************************************************/
bool put(const Key& k, const Value& v)
{
if (head == nullptr)
{
head = new Node(k, v);
return true;
}
if (head->key == k)
{
head->value = v;
return false;
}
Node* curr = head;
while (curr->next != nullptr)
{
if (curr->next->key == k)
{
curr->next->value = v;
return false;
}
curr = curr->next;
}
curr->next = new Node(k, v);
return true;
}
/******************************************
函数名称:
函数说明:
返回值:
*******************************************/
Value get(const Key& k)
{
Node* curr = head;
while (curr != nullptr)
{
if (curr->key == k)
return curr->value;
curr = curr->next;
}
throw std::overflow_error("can't get");
}
/*******************************************
函数名称: erase
函数说明: 删除key-value对应节点并判断是否删除
返回值: void
********************************************/
bool erase(const Key& k)
{
if (head == nullptr)
return false;
if (head->key == k)
{
delete head;
head = nullptr;
return true;
}
Node* curr = head;
Node* pre = nullptr;
while (curr->next != nullptr)
{
if (curr->next->key == k)
{
Node* temp = curr->next;
curr->next = curr->next->next;
delete temp;
return true;
}
pre = curr;
curr = curr->next;
}
if (curr->key == k)
{
delete curr;
pre->next = nullptr;
return true;
}
return false;
}
};
List *t = nullptr;
int kvcount = 0; //键值对个数
int listcount = 0; //链表个数
private:
/*******************************************
函数名称: isEmpty
函数说明: 判断哈希表是否为空
返回值: bool
*******************************************/
bool isEmpty()
{
return listcount == 0;
}
/******************************************
函数名称: hash
函数说明: 通过计算哈希值得到0--listcount的索引值
返回值: int
*******************************************/
int Myhash(const Key& k)
{
return (Hash()(k) & 0x7fffffff) % listcount;
}
public :
HashTable(int cap)
{
if (cap < 1)
std::underflow_error("cap error");
t = new List[cap];
listcount = cap;
}
/*******************************************
函数名称: put
函数说明: 存储新key-value
返回值: void
*******************************************/
void put(const Key& k,const Value& v)
{
int index = Myhash(k);
if (index > listcount - 1)
throw std::out_of_range("index out_of_range");
if (t[index].put(k, v))
++kvcount;
}
/******************************************
函数名称: get
函数说明: 搜索得到key对应的value
返回值: Value
*******************************************/
Value get(const Key& k)
{
int index = Myhash(k);
if (index > listcount - 1)
std::out_of_range("get out_of_range");
return t[index].get(k);
}
/******************************************
函数名称: erase
函数说明: 在散列表里删除key-value
返回值: void
*******************************************/
void erase(const Key& k)
{
int index = Myhash(k);
if (index > listcount - 1)
throw std::out_of_range("erase out_of_range");
if (t[index].erase(k))
--kvcount;
}
/******************************************
函数名称: size
函数说明: 返回key-value数量
返回值: int
*******************************************/
int size()
{
return kvcount;
}
~HashTable()
{
if (t != nullptr)
delete[]t;
}
};
main.cpp
#include <iostream>
#include "HashTable.h"
using namespace std;
int main()
{
HashTable<string, int> ht(13);
string a[] = { "Marco","Tom","Jerry","Mary","Happy","Sad","Ugly","Handsome","Cola","Thanks" };
for (int i = 0; i < 10; ++i)
ht.put(a[i],i);
cout << ht.get("Tom") << endl;
ht.erase("Marco");
cout << "size: " << ht.size() << endl;
try
{
cout << ht.get("Marco");
}
catch (const exception& e)
{
cout << e.what();
}
system("pause");
return 0;
}
运行: