实验内容:
(一)给定散列函数的除数D和操作数m,输出每次操作后的状态。
有以下三种操作:
- 插入x,若散列表已存在x,输出“Existed”,否则插入x到散列表中,输出所在的下标。
- 查询x,若散列表不含有x,输出“-1”,否则输出x对应下标。
- 删除x,若散列表不含有x,输出“Not Found”,否则输出删除x过程中移动元素的个数
(二)给定散列函数的除数D和操作数m,输出每次操作后的状态。
有以下三种操作:
5. 插入x,若散列表已存在x,输出"Existed"
6. 查询x,若散列表不含有x,输出"Not Found",否则输出x所在的链表长度
7. 删除x,若散列表不含有x,输出"Delete Failed",否则输出x所在链表删除x后的长度
样例:
(一)
输入:
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
(二)
输入:
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
代码实现(由上至下分别为题目一、题目二的C++代码):
#include <string>
#include <iostream>
using namespace std;
template <class K> class Hash;
template<>
class Hash<int>
{
public:
size_t operator()(const int theKey) const
{
return size_t(theKey);
}
};
template<class K, class E>
class hashTable
{
public:
hashTable(int theDivisor = 11);
~hashTable() { delete[] table; }
bool empty() const { return dSize == 0; }
int size() const { return dSize; }
pair<const K, E>* find(const K&) const;
void find2(const K&) const;
void insert(const pair<const K, E>&);
void output(ostream& out) const;
void erase(K&);
void erase1(K&);
protected:
int search(const K&) const;
pair<const K, E>** table;
Hash<K> hash;
int dSize;
int divisor;
};
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
{
int i = (int)hash(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>::erase1(K& theKey)
{
int b = search(theKey);
if (table[b] == NULL || table[b]->first != theKey)
cout << "Not Found" << endl;
else
{
table[b] = NULL;
int flag = 0;
int point = b, m = b, signal;
do
{
point = (point + 1) % divisor;
if (table[point] == NULL)
break;
signal = table[point]->first % divisor;
if ((signal <= m && m < point) || (point < signal && signal <= m) || (point < signal && m < point))
{
table[m] = table[point];
table[point] = NULL;
m = point;
flag++;
}
} while (table[(point + 1) % divisor] != NULL && point != b);
cout << flag << endl;
}
}
template<class K, class E>
void hashTable<K, E>::erase(K& theKey) {
int flag = 0;
int b = search(theKey);
if (table[b] == NULL) {
cout << "Not Found" << endl;
return;
}
table[b] = NULL;
int point = b;//当前的空位置
int i, t;
for (i = point;; i++) {//查找N后面NULL之前与d模相同的元素,若有将它移到空位上
if (table[(i + 1) % divisor] == NULL) {//||(table[(i + 1) % divisor]->first % divisor != point && table[(i + 2) % divisor] == NULL)) {
break;
}
if (table[(i + 1) % divisor]->first % divisor == point) {
table[point] = table[(i + 1) % divisor];
flag++;
table[(i + 1) % divisor] = NULL;
t = point;
point = i + 1;
i = t;
}
}
int c = point;
int C = c % divisor;
int C1 = (c + 1) % divisor;
while (table[C1] != NULL && C1 != (table[C1]->second % divisor)) {//后面NULL之前没有与c模相同的元素,移动。
table[C] = table[C1];
table[C1] = NULL;
c++;
C = c % divisor;
C1 = (c + 1) % divisor;
flag++;
}
dSize--;
cout << flag << endl;
}//停止条件:后面没有模相同的元素而且移动完成 或者 后面有相同的元素
template<class K, class E>
pair<const K, E>* hashTable<K, E>::find(const K& theKey) const
{
int b = search(theKey);
if (table[b] == NULL || table[b]->first != theKey)
return NULL;
return table[b];
}
template<class K, class E>
void hashTable<K, E>::find2(const K& theKey) const
{
int b = search(theKey);
if (table[b] == NULL || table[b]->first != theKey) {
cout << -1 << endl;
return;
}
cout << b << endl;
return;
}
template<class K, class E>
void hashTable<K, E>::insert(const pair<const K, E>& 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;
}
else {
}
}
}
template<class K, class E>
void hashTable<K, E>::output(ostream& out) const
{
for (int i = 0; i < divisor; i++)
if (table[i] == NULL)
cout << "NULL" << endl;
else
cout << table[i]->first << " "
<< table[i]->second << endl;
}
template <class K, class E>
ostream& operator<<(ostream& out, const hashTable<K, E>& x)
{
x.output(out); return out;
}
int main()
{
int D, m;
cin >> D >> m;
hashTable<int, int> a(D);
pair<int, int> q;
for (int i = 0; i < m; i++) {
int op, number;
cin >> op >> number;
if (op == 0) {
q.first = number; q.second = number;
a.insert(q);
}
else if (op == 1) {
q.first = number; q.second = number;
a.find2(q.first);
}
else if (op == 3) {
cout << a << endl;
}
else {
q.first = number; q.second = number;
a.erase1(q.first);
}
}
return 0;
}
#include <iostream>
#include <string>
using namespace std;
/// <summary>
///
///
///
template <class K> class Hash;
template<>
class Hash<int>
{
public:
size_t operator()(const int theKey) const
{
return size_t(theKey);
}
};
/// <summary>
///
///
///
template<class K, class E>
class dictionary
{
public:
virtual ~dictionary() {}
virtual bool empty() const = 0;
virtual int size() const = 0;
virtual pair<const K, E>* find(const K&) const = 0;
virtual void erase(const K&) = 0;
virtual void insert(const pair<const K, E>&) = 0;
};
/// <summary>
///
///
///
template <class K, class E>
struct pairNode
{
typedef pair<const K, E> pairType;
pairType element;
pairNode<K, E>* next;
pairNode(const pairType& thePair) :element(thePair) {}
pairNode(const pairType& thePair, pairNode<K, E>* theNext)
:element(thePair) {
next = theNext;
}
};
/// <summary>
///
///
///
template<class K, class E>
class sortedChain : public dictionary<K, E>
{
public:
sortedChain() { firstNode = NULL; dSize = 0; }
~sortedChain();
bool empty() const { return dSize == 0; }
int size() const { return dSize; }
pair<const K, E>* find(const K&) const;
void erase(const K&);
void insert(const pair<const K, E>&);
void output(ostream& out) const;
protected:
pairNode<K, E>* firstNode;
int dSize;
};
template<class K, class E>
sortedChain<K, E>::~sortedChain()
{
while (firstNode != NULL)
{
pairNode<K, E>* nextNode = firstNode->next;
delete firstNode;
firstNode = nextNode;
}
}
template<class K, class E>
pair<const K, E>* sortedChain<K, E>::find(const K& theKey) const
{
pairNode<K, E>* currentNode = firstNode;
while (currentNode != NULL &&
currentNode->element.first != theKey)
currentNode = currentNode->next;
if (currentNode != NULL && currentNode->element.first == theKey) {
cout << dSize<<endl;
return ¤tNode->element;
}
return NULL;
}
template<class K, class E>
void sortedChain<K, E>::insert(const pair<const K, E>& thePair)
{
pairNode<K, E>* p = firstNode,
* tp = NULL;
while (p != NULL && p->element.first < thePair.first)
{
tp = p;
p = p->next;
}
if (p != NULL && p->element.first == thePair.first)
{
cout << "Existed" << endl;
//p->element.second = thePair.second;
return;
}
pairNode<K, E>* newNode = new pairNode<K, E>(thePair, p);
if (tp == NULL) firstNode = newNode;
else tp->next = newNode;
dSize++;
return;
}
template<class K, class E>
void sortedChain<K, E>::erase(const K& theKey)
{
pairNode<K, E>* p = firstNode,
* tp = NULL;
while (p != NULL && p->element.first < theKey)
{
tp = p;
p = p->next;
}
if (p != NULL && p->element.first == theKey)
{
if (tp == NULL) firstNode = p->next;
else tp->next = p->next;
delete p;
dSize--;
cout << dSize<<endl;
return;
}
cout << "Delete Failed" << endl;
}
template<class K, class E>
void sortedChain<K, E>::output(ostream& out) const
{
for (pairNode<K, E>* currentNode = firstNode;
currentNode != NULL;
currentNode = currentNode->next)
out << currentNode->element.first << " "
<< currentNode->element.second << " ";
}
template <class K, class E>
ostream& operator<<(ostream& out, const sortedChain<K, E>& x)
{
x.output(out); return out;
}
/// <summary>
///
///
///
template<class K, class E>
class hashChains : public dictionary<K, E>
{
public:
hashChains(int theDivisor = 11)
{
divisor = theDivisor;
dSize = 0;
table = new sortedChain<K, E>[divisor];
}
~hashChains() { delete[] table; }
bool empty() const { return dSize == 0; }
int size() const { return dSize; }
pair<const K, E>* find(const K& theKey) const
{
return table[hash(theKey) % divisor].find(theKey);
}
void find1(const K& theKey) const
{
if (table[hash(theKey) % divisor].find(theKey) == NULL) {
cout << "Not Found" << endl;
}
else {
}
}
void insert(const pair<const K, E>& thePair)
{
int homeBucket = (int)hash(thePair.first) % divisor;
int homeSize = table[homeBucket].size();
table[homeBucket].insert(thePair);
if (table[homeBucket].size() > homeSize)
dSize++;
}
void erase(const K& theKey)
{
table[hash(theKey) % divisor].erase(theKey);
}
void output(ostream& out) const
{
for (int i = 0; i < divisor; i++)
if (table[i].size() == 0)
cout << "NULL" << endl;
else
cout << table[i] << endl;
}
protected:
sortedChain<K, E>* table;
Hash<K> hash;
int dSize;
int divisor;
};
template <class K, class E>
ostream& operator<<(ostream& out, const hashChains<K, E>& x)
{
x.output(out); return out;
}
int main()
{
int D, m;
cin >> D >> m;
hashChains<int, int> a(D);
pair<int, int> q;
for (int i = 0; i < m; i++) {
int op, number;
cin >> op >> number;
if (op == 0) {
q.first = number; q.second = number;
a.insert(q);
}
else if (op == 1) {
q.first = number; q.second = number;
a.find1(q.first);
}
else if (op == 3) {
cout << a << endl;
}
else {
q.first = number; q.second = number;
a.erase(q.first);
}
}
return 0;
}