赞
踩
代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <string>
using namespace std;
template <typename KEY, typename VALUE>
class CHashTable
{
#define TABLE_SIZE 128
public:
typedef struct tagNode
{
tagNode() {}
tagNode(const KEY &key, const VALUE &val) :
m_key(key), m_value(val), m_pNext(nullptr) { }
KEY m_key;
VALUE m_value;
struct tagNode *m_pNext;
} Node, *pNode;
// 构造函数
CHashTable() : m_nCnt(0)
{
for (size_t nIdx = 0; nIdx < TABLE_SIZE; ++nIdx)
{
m_pHashTable[nIdx] = nullptr;
}
}
// 析构函数
~CHashTable()
{
ReleaseTable();
}
// 拷贝构造函数
CHashTable(const CHashTable &hashTbl);
// 移动构造函数
CHashTable(CHashTable &&hashTbl);
// 赋值运算符重载
CHashTable &operator=(const CHashTable &hashTbl);
// 删除hash表结点
bool Delete(const KEY &key, const VALUE &val);
// 向hash表插入键值对
bool Insert(const KEY &key, const VALUE &Value);
// 查找hash表的节点内容
bool Find(const KEY &key, vector<VALUE> &rVecValue) const;
// 打印hash表内容
void PrintHashTbl() const;
private:
// 释放hash表
void ReleaseTable();
private:
Node *m_pHashTable[TABLE_SIZE];
size_t m_nCnt;
};
template <typename KEY, typename VALUE>
CHashTable<KEY, VALUE> &CHashTable<KEY, VALUE>::operator=(const CHashTable &hashTbl)
{
pNode pCurNode = nullptr;
pNode pTmpNode = nullptr;
pNode pNewNode = nullptr;
// 先对自己进行一次释放操作
ReleaseTable();
// 清空自己的数组内容
//memset(m_pHashTable, 0, sizeof(Node *) * TABLE_SIZE);
// 获取结点元素的数量
m_nCnt = hashTbl.m_nCnt;
for (size_t nIdx = 0; nIdx < TABLE_SIZE; ++nIdx)
{
// 获取当前数组内存储的头结点指针
pCurNode = hashTbl.m_pHashTable[nIdx];
// 如果存在则进行深拷贝, 否则直接赋nullptr
if (!pCurNode)
{
m_pHashTable[nIdx] = nullptr;
continue;
}
while (pCurNode)
{
// 分配新结点
pNewNode = new Node(pCurNode->m_key, pCurNode->m_value);
if (!pNewNode)
{
ReleaseTable();
return(*this);
}
if (!m_pHashTable[nIdx])
{
// 如果一个结点也没有直接赋值到头结点内部
m_pHashTable[nIdx] = pNewNode;
pTmpNode = pNewNode;
}
else
{
// 将新结点插入到尾部
pTmpNode->m_pNext = pNewNode;
pTmpNode = pNewNode;
}
pCurNode = pCurNode->m_pNext;
}
}
return(*this);
}
template <typename KEY, typename VALUE>
CHashTable<KEY, VALUE>::CHashTable(const CHashTable &hashTbl)
{
pNode pCurNode = nullptr;
pNode pTmpNode = nullptr;
pNode pNewNode = nullptr;
// 清空自己的数组内容
memset(m_pHashTable, 0, sizeof(Node *) * TABLE_SIZE);
// 获取结点元素的数量
m_nCnt = hashTbl.m_nCnt;
for (size_t nIdx = 0; nIdx < TABLE_SIZE; ++nIdx)
{
// 获取当前数组内存储的头结点指针
pCurNode = hashTbl.m_pHashTable[nIdx];
// 如果存在则进行深拷贝, 否则直接赋nullptr
if (!pCurNode)
{
m_pHashTable[nIdx] = nullptr;
continue;
}
while (pCurNode)
{
// 分配新结点
pNewNode = new Node(pCurNode->m_key, pCurNode->m_value);
if (!pNewNode)
{
ReleaseTable();
return;
}
if (!m_pHashTable[nIdx])
{
// 如果一个结点也没有直接赋值到头结点内部
m_pHashTable[nIdx] = pNewNode;
pTmpNode = pNewNode;
}
else
{
// 将新结点插入到尾部
pTmpNode->m_pNext = pNewNode;
pTmpNode = pNewNode;
}
pCurNode = pCurNode->m_pNext;
}
}
}
template <typename KEY, typename VALUE>
CHashTable<KEY, VALUE>::CHashTable(CHashTable &&hashTbl)
{
// 进行移动
m_nCnt = hashTbl.m_nCnt;
memcpy(m_pHashTable, hashTbl.m_pHashTable, TABLE_SIZE * sizeof(Node *));
// 清空操作
hashTbl.m_nCnt = 0;
memset(hashTbl.m_pHashTable, 0, TABLE_SIZE * sizeof(Node *));
}
template <typename KEY, typename VALUE>
void CHashTable<KEY, VALUE>::ReleaseTable()
{
for (size_t nIdx = 0; nIdx < TABLE_SIZE; ++nIdx)
{
if (m_pHashTable[nIdx])
{
pNode pCurNode = m_pHashTable[nIdx];
pNode pTmpNode = nullptr;
while (pCurNode)
{
// 保存下一个结点
pTmpNode = pCurNode->m_pNext;
// 删除当前结点
delete pCurNode;
pCurNode = nullptr;
// 当前结点指向下一个结点
pCurNode = pTmpNode;
}
m_pHashTable[nIdx] = nullptr;
}
}
m_nCnt = 0;
}
template <typename KEY, typename VALUE>
bool CHashTable<KEY, VALUE>::Delete(const KEY &key, const VALUE &val)
{
size_t nHash = 0;
pNode pCurNode = nullptr;
// 计算hash值
nHash = hash<KEY>{}(key) % TABLE_SIZE;
// 获取hash表头结点
pCurNode = m_pHashTable[nHash];
if (!pCurNode)
{
return(false);
}
while (pCurNode)
{
// 如果找到了结点
if (pCurNode->m_key == key && pCurNode->m_value == val)
{
pNode pHeadNode = m_pHashTable[nHash];
// 头结点的内容覆盖掉被删除的结点
pCurNode->m_key = pHeadNode->m_key;
pCurNode->m_value = pHeadNode->m_value;
// 删除头结点
m_pHashTable[nHash] = pHeadNode->m_pNext;
delete pHeadNode;
pHeadNode = nullptr;
--m_nCnt;
return(true);
}
pCurNode = pCurNode->m_pNext;
}
return(false);
}
template <typename KEY, typename VALUE>
bool CHashTable<KEY, VALUE>::Find(const KEY &key, vector<VALUE> &rVecValue) const
{
size_t nHash = 0;
pNode pCurNode = nullptr;
// 计算hash值
nHash = hash<KEY>{}(key) % TABLE_SIZE;
// 获取hash表头结点
pCurNode = m_pHashTable[nHash];
if (!pCurNode)
{
return(false);
}
while (pCurNode)
{
if (pCurNode->m_key == key)
{
rVecValue.push_back(pCurNode->m_value);
}
pCurNode = pCurNode->m_pNext;
}
return(true);
}
template <typename KEY, typename VALUE>
void CHashTable<KEY, VALUE>::PrintHashTbl() const
{
for (size_t nIdx = 0; nIdx < TABLE_SIZE; ++nIdx)
{
if (m_pHashTable[nIdx])
{
pNode pCurNode = m_pHashTable[nIdx];
cout << "key: " << nIdx << endl;
while (pCurNode)
{
cout << "value: " << pCurNode->m_value << endl;
pCurNode = pCurNode->m_pNext;
}
cout << endl;
}
}
}
template <typename KEY, typename VALUE>
bool CHashTable<KEY, VALUE>::Insert(const KEY &key, const VALUE &Value)
{
size_t nIdx = 0;
pNode pNewNode = nullptr;
// 计算出key的hash值作为索引
nIdx = hash<KEY>{}(key) % TABLE_SIZE;
// 分配新结点
pNewNode = new Node(key, Value);
if (!pNewNode)
{
return(false);
}
if (m_pHashTable[nIdx])
{
// 如果说m_pHashTable[nIdx]则进行头插法插入
pNewNode->m_pNext = m_pHashTable[nIdx]->m_pNext;
m_pHashTable[nIdx]->m_pNext = pNewNode;
}
else
{
// 如果说不存在则直接赋值给头结点
m_pHashTable[nIdx] = pNewNode;
}
++m_nCnt;
return(true);
}
int main()
{
CHashTable<string, int> HashTbl;
vector<int> vec;
HashTbl.Insert("hello", 65);
HashTbl.Insert("yyds", 215);
HashTbl.Insert("what", 184);
HashTbl.Insert("what", 36);
HashTbl.Insert("what", 24);
HashTbl.Insert("r23jlf", 65);
if (HashTbl.Find("what", vec))
{
for (size_t nIdx = 0; nIdx < vec.size(); ++nIdx)
{
cout << vec[nIdx] << " ";
}
cout << endl;
}
HashTbl.PrintHashTbl();
HashTbl.Delete("what", 36);
HashTbl.PrintHashTbl();
CHashTable<string, int> hashTbl1 = HashTbl;
hashTbl1 = HashTbl;
hashTbl1.PrintHashTbl();
system("pause");
return(0);
}
(完)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。