问题 B: 链地址法的哈希表
题目描述
实现链地址法的哈希表,表的构造参见教材图
输入
第一行只包含一个整数n,表示哈希表的大小。
随后为哈希表的操作系列,每个操作一行,具体见样例。
输出
如果输入为"insert k",如果表中k已经存在则输出"k is already existed in hash table",否则将k插入后什么也不输出。
如果输入为"search k “,如果表中k已经存在则输出"k is found”,否则输出 “k is not found”。
如果输入为"delete k",如果表中k已经存在,则删除后则输出整个表,否则输出"80 is not existed in hash table"。
如果输入为"print",则输出整个表。
样例输入 Copy
13
insert 19
insert 14
insert 14
insert 23
insert 1
print
search 68
insert 68
insert 20
insert 84
insert 27
search 68
insert 55
insert 11
insert 10
insert 79
print
insert 27
delete 1
delete 80
delete 19
delete 55
样例输出 Copy
14 is already existed in hash table
Print the hash table
[0]
[1]->14->1
[2]
[3]
[4]
[5]
[6]->19
[7]
[8]
[9]
[10]->23
[11]
[12]
68 is not found
68 is found
Print the hash table
[0]
[1]->14->1->27->79
[2]
[3]->68->55
[4]
[5]
[6]->19->84
[7]->20
[8]
[9]
[10]->23->10
[11]->11
[12]
27 is already existed in hash table
Print the hash table
[0]
[1]->14->27->79
[2]
[3]->68->55
[4]
[5]
[6]->19->84
[7]->20
[8]
[9]
[10]->23->10
[11]->11
[12]
80 is not existed in hash table
Print the hash table
[0]
[1]->14->27->79
[2]
[3]->68->55
[4]
[5]
[6]->84
[7]->20
[8]
[9]
[10]->23->10
[11]->11
[12]
Print the hash table
[0]
[1]->14->27->79
[2]
[3]->68
[4]
[5]
[6]->84
[7]->20
[8]
[9]
[10]->23->10
[11]->11
[12]
c++实现:
#include <iostream>
#include <iomanip>
#include <cstdio>
using namespace std;
#define DEBUG cout << __LINE__ << endl;
typedef struct node {
int key;
struct node *next;
} Node, *PNode;
typedef struct {
PNode *elem;
int sz; //size of hashtable
} HashTable;
void InitHashTable(HashTable &ht, int n)
{
ht.sz = n;
//申请大小为n的指针数组,每个指针初始化为NULL
ht.elem = new PNode[n]();
}
//如果表中存在k,返回指向对应结点的指针,否则返回NULL
PNode SearchHashTable(HashTable ht, int k)
{
/****在此下面完成代码************/
PNode temp;
int index = k % ht.sz;
temp = ht.elem[index];
while(temp)
{
if(temp->key == k)
return temp;
else
temp = temp->next;
}
return NULL;
/********************************/
}
//将k插入ht中对应的链表尾部,如果表中k已经存在,直接返回false,否则插入k后返回true
bool InsertHashTable(HashTable &ht, int k)
{
/****在此下面完成代码************/
if(SearchHashTable(ht,k))
return false;
int index = k % ht.sz;
Node *temp = ht.elem[index];
Node *s;
s = new Node;
s->key = k;
s->next = NULL;
if (temp == NULL) {
ht.elem[index] = s;
return true;
}
// DEBUG
while(temp->next)
temp = temp->next;
temp->next = s;
return true;
/***********************************/
}
//删除表中韩关键字k的结点并返回true。如果不存在,直接返回false。
bool DeleteHashTable(HashTable &ht, int k)
{
/****在此下面完成代码************/
//DeleteHashTable()函数的另一种写法。
// if (ht.elem[k%ht.sz] && ht.elem[k%ht.sz]->key==k ) {
// ht.elem[k%ht.sz] = ht.elem[k%ht.sz]->next;
// return true;
// }
// for (PNode p = ht.elem[k%ht.sz]; p&&p->next; p=p->next){
// if ( p->next->key == k ){
// p->next = p->next->next;
// return true;
// }
// }
// return false;
if(SearchHashTable(ht,k))
{
int index = k % ht.sz;
PNode temp = ht.elem[index];
while(temp)
{
if(temp->key == k)
{
ht.elem[index] = ht.elem[index]->next;
return true;
}
else if(temp->next && temp->next->key == k)
{
temp->next = temp->next->next;
return true;
}
temp = temp->next;
}
return false;
}
else
return false;
/***********************************/
}
static void PrintLinklist(PNode h)
{
for(PNode p = h; p; p = p->next) {
cout << "->" << p->key;
}
cout << endl;
}
void PrintHashTable(HashTable ht)
{
cout << "Print the hash table\n";
for(int i = 0; i < ht.sz; i++) {
cout << '[' << i << ']';
PrintLinklist(ht.elem[i]);
}
}
void DestroyHashTable(HashTable &ht)
{
//You should do this!
}
int main()
{
int n;
HashTable ht;
string op;
cin >> n;
InitHashTable(ht, n);
while(cin >> op)
{
int k;
if(op == "insert")
{
cin >> k;
if(!InsertHashTable(ht, k))
cout << k << " is " << "already existed in hash table\n";
}
else if(op == "search")
{
cin >> k;
cout << k << " is" << (SearchHashTable(ht, k) ? "" : " not") << " found\n";
}
else if(op == "delete")
{
cin >> k;
if(DeleteHashTable(ht, k))
PrintHashTable(ht);
else
cout << k << " is " << "not existed in hash table\n";
}
else if(op == "print")
PrintHashTable(ht);
}
DestroyHashTable(ht);
return 0;
}//main
总结:
1、主要卡在了插入函数和删除函数,插入函数要注意指针的顺序,删除函数中,若改结点本身,应该直接改,而不是改temp所指,这几个改了半天,基础还是不扎实。。