要求
使用线性开型寻址实现
描述
给定散列函数的除数D和操作数m,输出每次操作后的状态。
有以下三种操作:
- 插入x,若散列表已存在x,输出“Existed”,否则插入x到散列表中,输出所在的下标。
- 查询x,若散列表不含有x,输出“-1”,否则输出x对应下标。
- 删除x,若散列表不含有x,输出“Not Found”,否则输出删除x过程中移动元素的个数。
格式
输入格式
第一行两个整数D,m。分别代表散列函数的除数D和操作数m。
接下来m行,每行两个整数opt和x,分别代表操作类型和操作数。
若opt为0,代表插入x。
若opt为1,代表查询x。
若opt为2,代表删除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
输出
-1
1
6
5
2
0
3
3
3
6
5
1
样例二
输入
20 30
0 84
0 15
0 54
2 15
2 84
1 54
2 54
0 89
1 89
0 13
0 48
2 89
0 60
0 24
1 13
0 6
1 24
0 31
2 60
2 48
0 49
0 9
1 6
1 13
0 33
2 49
0 60
1 6
2 9
1 60
输出
4
15
14
0
0
14
0
9
9
13
8
0
0
4
13
6
4
11
0
0
9
10
6
13
14
1
0
6
0
0
限制
1s, 1024KiB for each test case.
#include <iostream>
using namespace std;
template<class K, class E>
class hashTable {
public:
hashTable(int theDivisor = 11);
void find(const K &) const;
//返回关键字theKey匹配的数对的指针,若不存在匹配的数对,则返回NULL
void insert( const pair<const K, E>&);
//在字典中插入一个数对thePair,若存在关键字相同的数对,则覆盖
void erase(const K &theKey);
int search(const K& theKey) const;
protected:
pair<const K, E> **table; // 散列表
int divisor; // 散列函数的除数
int dSize; // 字典中数对的个数
};
template<class K, class E>
hashTable<K,E>::hashTable(int theDivisor)
{// 构造函数
divisor = theDivisor;
dSize=0;
// 分配和初始化散列表数组
table = new pair<const K, E>* [divisor];
for (int i = 0; i < divisor; i++) //将所有桶置空
table[i] = NULL;
}
template<class K, class E>
int hashTable<K,E>::search(const K& theKey) const
{// 搜索一个公开地址散列表,查找关键字为theKey的数对
// 如果匹配的数对存在,则返回它的位置
// 否则返回关键字为theKey的数对可以插入的位置
int i =(int) theKey % divisor; // 起始桶
int j = i; // 从起始桶处开始
do {
if (table[j]==NULL || table[j]->first == theKey) return j;
j = (j + 1) % divisor; // 下一个桶
} while (j != i); // 又返回起始桶?
return j; // 表已经满
}
template<class K, class E>
void hashTable<K,E>::find(const K& theKey) const
{//返回关键字theKey匹配的数对的指针
//若不存在匹配的数对,则返回NULL
//搜索散列表
int b = search(theKey);
//判断table[b]是否是匹配数对
if (table[b] ==NULL || table[b]->first != theKey)
cout<<-1<<endl;//未找到匹配数对
else cout<<b<<endl; //找到匹配数对
}
template<class K, class E>
void hashTable<K,E>::insert( const pair<const K, E>& thePair)
{//在字典中插入一个数对thePair,若存在关键字相同的数对,
int b = search(thePair.first);
// 检查匹配的数对是否存在
//没有匹配的数对,且表不满,则插入数对
if (table[b]==NULL)
{table[b] =new pair<const K,E>(thePair) ;
dSize++;
cout<<b<<endl;}
else if (table[b]->first == thePair.first )
cout<<"Existed"<<endl;
}
// 删除
template<class K, class E>
void hashTable<K, E>::erase(const K& theKey) {
int b = search(theKey);
if (table[b] == NULL || table[b]->first != theKey) {
cout << "Not Found" << endl;
} else {
table[b] = NULL; // 删除
int n = b, a = b; // 设置删除点,便于遍历
b = (b + 1) % divisor; // 从删除的后一位开始遍历
int x = 0; // 记录移动个数
while (table[b] != NULL && b != n) { // 没有遇到空桶或者没有遍历一遍的话继续执行
int m = (int) table[b]->first % divisor; // b索引中数字应该在的索引位置
if ((a < b && b < m) || (b < m && m <= a) || (m <= a && a < b)) {
table[a] = table[b];
a = b;
x++;
}
b = (b + 1) % divisor; // 指针移动
}
table[a] = NULL; // 最后进行删除,使其等于空
cout << x << endl;
}
}
int main(){
int D, m;
cin >> D >> m;
hashTable<int,int> a(D);
for(int i = 0; i < m; i++){
int op, x;
cin >> op >> x;
switch(op){
case 0: { pair<int, int>p(x, 0);a.insert(p);}
break;
case 1: { a.find(x);}
break;
case 2: a.erase(x);
break;
}
}
return 0;
}
要求
使用链表散列方式
描述
给定散列函数的除数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;
struct Node {
int element;
Node *next;
Node(int theElement) {
element = theElement;
}
};
class linearListHashtable {
public:
linearListHashtable() {
firstNode = NULL;
size = 0;
}
~linearListHashtable();
void insert(int element);
void find(int element);
void erase(int element);
private:
Node *firstNode;
int size;
};
void linearListHashtable::insert(int element) {
int flag = 0;
Node *cur = firstNode;
if(cur==NULL){firstNode=new Node(element);size++;firstNode->next=NULL;return ;}
while (cur->next !=NULL ) {
if (element == cur->element) {
cout << "Existed" << endl;
flag = 1;
break;
}
cur = cur->next;
}
if(cur->element==element&&flag==0){cout<<"Existed"<<endl;flag=1;}
if (flag != 1)
{cur->next = new Node(element);
size++;
cur->next->next=NULL;}
}
void linearListHashtable::find(int element) {
int flag = 0;
Node *cur = firstNode;
if(firstNode==NULL){cout << "Not Found" << endl;return ;}
while (cur ->next!=NULL ) {
if (element == cur->element) {
cout << size << endl;
flag = 1;
break;
}
cur = cur->next;
}if(cur->element==element&&flag==0){
cout<<size<<endl;
flag=1;
}
if (flag == 0)
cout << "Not Found" << endl;
}
void linearListHashtable::erase(int element) {
int flag = 0;
if(firstNode==NULL){cout << "Delete Failed" << endl;return;}
int Element=firstNode->element;
if (firstNode->element == element) {
firstNode = firstNode->next;
size--;
cout << size << endl;
return;
}
Node *cur = firstNode->next;
Node *pre = firstNode;
while (cur !=NULL ) {
if (element == cur->element) {
pre->next = pre->next->next;
size--;
cout << size<<endl;
flag = 1;
break;
}
cur = cur->next;
pre = pre->next;
}
if (flag == 0)
cout << "Delete Failed" << endl;
}
int main() {
int D, m;
cin >> D>>m;
linearListHashtable *a = new linearListHashtable[D];
int opt;
int value = 0, index = 0;
while (m--) {
cin >> opt;
switch (opt) {
case 0: {
cin >> value;
index = value % D;
a[index].insert(value);
}
break;
case 1: {
cin >> value;
index = value % D;
a[index].find(value);
}
break;
case 2: {
cin>>value;
index =value % D;
a[index].erase(value);
}
break;
}
}
return 0;
}
标签:数据结构,int,NULL,next,theKey,列表,element,山东大学
From: https://www.cnblogs.com/lyz103/p/17355583.html