散列表中的平方探测法
程序员文章站
2022-07-15 14:15:11
...
试题描述:
设计散列表实现电话号码查找系统。
2.基本要求:
(1)设每个记录有下列数据项:电话号码、用户名、地址;
(2)从键盘输入各记录,分别以电话号码和用户名为关键字建立散列表;
(3)采用一定的方法解决冲突;
(4)查找并显示给定电话号码的记录;
(5)查找并显示给定用户名的记录
我这里偷了个懒,注意 以用户名查找 时只能查找以用户名添加的用户,同样 以电话号码查找 时只能查找以电话号码添加的用户
#include <bits/stdc++.h>
using namespace std;
typedef struct HashTbl *HashTable;
typedef struct HashEntry Cell;
enum status {
Empty,
Exist
};
struct HashEntry {
string name;
string number;
string location;
enum status Info;
};
struct HashTbl {
int TableSize;
Cell *TheCells;
};
int NextPrime(int TableSize) {
int i;
if (TableSize % 2 == 0) TableSize++;
while (1) {
for (i = 3; i * i <= TableSize; i += 2)
if (TableSize % i == 0) break;
if (i * i >= TableSize) return TableSize;
TableSize += 2;
}
}
int Hash(string Key, int TableSize) {
unsigned int HashVal = 0, i = 0;
while (i < Key.length()) {
HashVal = (HashVal << 5) + Key[i++];
}
return HashVal % TableSize;
}
HashTable InitializeTable(int TableSize) {
HashTable H = (HashTable)malloc(sizeof(struct HashTbl));
H->TableSize = NextPrime(TableSize);
H->TheCells = (Cell *)malloc(sizeof(Cell) * H->TableSize);
for (int i = 0; i < H->TableSize; ++i) {
H->TheCells[i].Info = Empty;
}
return H;
}
int Find(string Str, HashTable H, int flag) {
int CurrentPos = Hash(Str, H->TableSize);
int CollisionNum = 0;
string Choice = flag ? H->TheCells[CurrentPos].name : H->TheCells[CurrentPos].number;
while (H->TheCells[CurrentPos].Info != Empty && Choice != Str) {
CurrentPos += 2 * ++CollisionNum - 1;
CurrentPos %= H->TableSize;
}
return CurrentPos;
}
void Insert(Cell Key, HashTable H,int flag) {
string Str=flag?Key.name:Key.number;
int pos = Find(Str, H, flag);
H->TheCells[pos]=Key;
}
void Show(HashTable H){
for(int i=0;i<H->TableSize;i++){
if(H->TheCells[i].Info!=Empty)
cout<<"用户名:"<<H->TheCells[i].name<<" 电话号码:"<<H->TheCells[i].number<<" 地址:"<<H->TheCells[i].location<<endl;
}
}
int main(int argc, char const *argv[]) {
HashTable Table = InitializeTable(10000);
char c='y';
while(c=='y'){
system("cls");
cout<<"请输入操作:"<<endl;
cout<<" n:以用户名为关键字添加用户(英文输入)"<<endl;
cout<<" c:以电话号码为关键字添加用户"<<endl;
cout<<" s:显示所有用户"<<endl;
cout<<" F:输入用户名查找"<<endl;
cout<<" f:输入电话号码查找"<<endl;
cin>>c;
Cell tmp;
int pos;
string Str;
switch (c){
case 'n':
cout<<"请输入用户名:";
cin>>tmp.name;
cout<<"请输入电话号码:";
cin>>tmp.number;
cout<<"请输入地址:";
cin>>tmp.location;
tmp.Info=Exist;
Insert(tmp,Table,1);
break;
case 'c':
cout<<"请输入用户名:";
cin>>tmp.name;
cout<<"请输入电话号码:";
cin>>tmp.number;
cout<<"请输入地址:";
cin>>tmp.location;
tmp.Info=Exist;
Insert(tmp,Table,0);
break;
case 's':
Show(Table);
break;
case 'F':
cout<<"请输入用户名:";
cin>>Str;
pos=Find(Str,Table,1);
cout<<"用户名:"<<Table->TheCells[pos].name<<" 电话号码:"<<Table->TheCells[pos].number<<" 地址:"<<Table->TheCells[pos].location<<endl;
break;
case 'f':
cout<<"请输入电话号码:";
cin>>Str;
pos=Find(Str,Table,0);
cout<<"用户名:"<<Table->TheCells[pos].name<<" 电话号码:"<<Table->TheCells[pos].number<<" 地址:"<<Table->TheCells[pos].location<<endl;
break;
default:
cout<<"无该操作!"<<endl;
}
cout<<"继续或退出(y/任意键):";
cin>>c;
}
return 0;
}