散列表
使用链表散列方式
描述
给定散列函数的除数D和操作数m,输出每次操作后的状态。
有以下三种操作:
插入x,若散列表已存在x,输出"Existed"
查询x,若散列表不含有x,输出"Not Found",否则输出x所在的链表长度
删除x,若散列表不含有x,输出"Delete Failed",否则输出x所在链表删除x后的长度
格式
输入格式
第一行两个整数D(1<=D<=3000)和m(1<=m<=3000),其中D为散列函数的除数,m为操作数。
接下来的m行,每行两个整数opt和x,分别代表操作类型和操作数。
若opt为0,则代表向散列表中插入x;
若opt为1,代表查询散列表中x是否存在;
若opt为2,(如果散列表中含有x),删除x。
数据保证散列表不会溢出。
输出格式
按需输出。
样例1
样例输入
7 12
1 21
0 1
0 13
0 5
0 23
0 26
0 33
1 33
1 33
1 13
1 5
1 1
样例输出
Not Found
3
3
1
3
1
样例2
样例输入
7 15
2 10
0 10
0 10
2 10
1 10
0 10
1 10
0 17
0 2
0 16
0 11
2 2
2 10
1 11
1 17
样例输出
Delete Failed
Existed
0
Not Found
1
1
1
1
1
数据范围
对于前60%的数据,只包含插入和查询操作
对于后40%的数据,包含插入、查询与删除操作
#include<iostream>
using namespace std;
//创建链表结构
template <class T>
struct chainNode
{
T element;
chainNode<T> *next;
chainNode() {}
chainNode(const T& element)
{this->element = element;}
chainNode(const T& element, chainNode<T>* next)
{this->element = element;
this->next = next;}
};
template<class T>
class sortedChain
{
public:
sortedChain() {firstNode = NULL; dSize = 0;}//构造函数
~sortedChain();//析构函数
bool empty() const {return dSize == 0;}
int size() const {return dSize;}
void find(const T&) const;
void erase(const T&);
void insert(const T&);
private:
chainNode<T>* firstNode;
int dSize; //字典中的数对
};
template<class T>
sortedChain<T>::~sortedChain()
{
while (firstNode != NULL)
{
chainNode<T>* nextNode = firstNode->next;
delete firstNode;
firstNode = nextNode;
}
}
//查找
template<class T>
void sortedChain<T>::find(const T& theKey) const
{
chainNode<T>* currentNode = firstNode;
while (currentNode != NULL &&
currentNode->element!= theKey)
currentNode = currentNode->next;
if (currentNode != NULL && currentNode->element == theKey)
cout<<size()<<endl;//找到了就输出数对个数
else
cout<<"Not Found"<<endl;//没找到就输出Not Found
}
//插入
template<class T>
void sortedChain<T>::insert(const T& theKey)
{
chainNode<T> *p = firstNode,
*tp = NULL; //移动指针tp
while (p != NULL && p->element < theKey)
{
tp = p;
p = p->next;
}
if (p != NULL && p->element == theKey)
{//如果已经存在,则输出Existed
cout<<"Existed"<<endl;
return;
}
chainNode<T> *newNode = new chainNode<T>(theKey,p);
if (tp == NULL) firstNode = newNode;
else tp->next = newNode;
dSize++;
return;
}
//删除
template<class T>
void sortedChain<T>::erase(const T& theKey)
{
chainNode<T> *p = firstNode,
*tp = NULL;
while (p != NULL && p->element < theKey)
{
tp = p;
p = p->next;
}
if (p != NULL && p->element == theKey)
{
if (tp == NULL) firstNode = p->next;
else tp->next = p->next;
delete p;
dSize--;
cout<<dSize<<endl;
}
else
cout<<"Delete Failed"<<endl;
}
template<class T>
class hashChains
{
public:
hashChains(int theDivisor = 11)//构造函数
{
divisor = theDivisor;
dSize = 0;
table = new sortedChain<T> [divisor];
}
~hashChains(){delete [] table;}//析构函数
bool empty() const {return dSize == 0;}
int size() const {return dSize;}
void find(const T& theKey) const
{
table[theKey % divisor].find(theKey);
}
void insert(const T& theKey)
{
int homeBucket = theKey % divisor;
int homeSize = table[homeBucket].size();
table[homeBucket].insert(theKey);
if (table[homeBucket].size() > homeSize)
dSize++;
}
void erase(const T& theKey)
{
table[theKey % divisor].erase(theKey);
}
protected:
sortedChain<T>* table; // hash table
//hash<K> hash;
int dSize; // 字典中数对个数
int divisor; //散列函数除数
};
//0插入,1查询,2删除
int main()
{
int D,m,opt,x;
cin>>D>>m;
hashChains<int> h(D);
for(int i=0;i<m;i++){
cin>>opt;
switch(opt){
case 0:
cin>>x;
h.insert(x);
break;
case 1:
cin>>x;
h.find(x);
break;
case 2:
cin>>x;
h.erase(x);
break;
}
}
return 0;
}