基本思想:
-
将所有哈希地址为
i
的元素构成一个称为同义词链的链表,并将链表的头指针存在哈希表的第i
个单元中,同义词链表可以是单链表,也可以是双链表 -
查找、插入和删除主要在同义词链中进行。适用于经常进行插入和删除的情况。
代码实现:
//.h
#pragma once
#include<iostream>
#define HashSize 20
using std::cout; using std::endl;
template<class T>
struct Node
{
T val;
Node * next;
Node() : val(), next(nullptr) {};
Node(T v) : val(v), next(nullptr) {};
Node(T v, Node* n) : val(v), next(n) {};
};
template<class T>
class HashTable
{
private:
Node<T> *node[HashSize];
int Hash(T val) {
return val % HashSize;
}
public:
HashTable();
~HashTable();
bool Insert(T val);
Node<T>* Search(T val);
bool Detlete(T val);
void printTable();
};
//.cpp
#include"HashTable.h"
template<class T>
HashTable<T>::HashTable()
{
for (int i = 0; i < HashSize; ++i) {
node[i] = nullptr;
}
}
template<class T>
HashTable<T>::~HashTable()
{
}
//插入
template<class T>
bool HashTable<T>::Insert(T val)
{
Node<T> * head = node[Hash(val)];
Node<T> * newNode = new Node<T>(val);
if (head == nullptr) {
head = newNode;
}
else if (val < head->val) {
newNode->next = head;
head = newNode;
}
else {
Node<T> * p = head;
while (p != nullptr && p->next != nullptr && p->val < val) {
p = p->next;
}
newNode->next = p->next;
p->next = newNode;
}
node[Hash(val)] = head;
return true;
}
//搜索
template<class T>
Node<T>* HashTable<T>::Search(T val)
{
Node<T> *head = node[Hash(val)];
while (head != nullptr && head->val != val) {
head = head->next;
}
return head ? head : nullptr;
}
//删除
template<class T>
bool HashTable<T>::Detlete(T val)
{
if (this->Search(val)) {
Node<T> *head = node[Hash(val)];
while (head != nullptr && head->next != nullptr && head->next->val != val) {
head = head->next;
}
if (head->next == nullptr) {
head = nullptr;
}
else {
head->next = head->next->next;
}
return true;
}
else
return false;
}
template<class T>
void HashTable<T>::printTable()
{
for (int i = 0; i < HashSize; ++i) {
Node<T> *p = node[i];
while (p != nullptr) {
cout << p->val << "->";
p = p->next;
}
cout << "N" << endl;
}
}
//测试
#include"HashTable.h"
#include"HashTable.cpp"
using namespace std;
int main()
{
HashTable<int> mhash;
for (int i = 0; i < 60; i += 2) {
mhash.Insert(i);
}
for (int i = 1; i < 50; i += 2) {
mhash.Insert(i);
}
if(mhash.Search(46))
cout << mhash.Search(46)->val << " ";
else
cout << "nullptr ";
if (mhash.Search(51))
cout << mhash.Search(51) << endl;
else
cout << "nullptr " << endl;
mhash.printTable();
cout << "Detlete 46: ";
if(mhash.Detlete(46))
cout<<"Succeed"<<endl;
else cout << "Failed" << endl;
cout << "Detlete 79: ";
if (mhash.Detlete(79))
cout << "Succeed" << endl;
else cout << "Failed" << endl;
mhash.printTable();
}
输出