1.问题描述和要求
问题描述:为某个单位建立一个员工通讯录管理系统,可以方便查询每一个员工的电话与地址。设计散列表存储,设计并实现通讯录查找系统。
基本要求:
(1)每个记录有下列数据项:电话号码、用户名、地址;
(2)从键盘输入信息,以电话号码为关键字建立散列表;
(3)采用二次探测再散列法解决冲突;
(4)查找并显示给定电话号码的记录;
(5)通讯录信息文件保存。
2.问题分析
(1)建立结构体,储存数据项
(2)创建散列表
(3)用二次探测解决散列表冲突
(4)实现散列表的查找
3.数据结构及关键技术
1.散列表
(1)散列表的思想:在元素的存储位置和和其关键字之间建立某种直接关系,那么在查找过程中就无需做比较和很少的比较,按照这种由关键字查找的方法就叫散列查找。
(2)散列表的冲突:对于不同的关键词可能会有相同的散列地址,这种现象是冲突。
(3)二次探测再散列法:关键字值的增量序列为1的平方,-1的平方,2的平方,-2的平方,……,k的平方,-k的平方。
2.从文件中读入数据
c++中有文件输入类ofstream,包含在头文件fstream中。
4.完整源代码
#include<iostream>
#include<math.h>
#include<cstring>
#include<fstream>
#include<iomanip>
using namespace std;
#define maxsize 20
#define ok 1
#define error 0
typedef struct{ //通讯录信息数据类型
long long int number;
char name[20];
char address[20];
}infor;
typedef struct{ //哈希表的创建函数
infor *elem;
int length;
}hashtable;
int Inithash(hashtable &h) //初始化哈希表
{
h.elem = new infor[maxsize];
if(!h.elem)
exit(0);
h.length = maxsize;
for(int i = 0; i < maxsize; i++)
h.elem[i].number = 0;
return ok;
}
int hash(long long int key) //求关键词的值
{
return int(key%100/5);
}
int Inserthash(hashtable &h,infor e) //插入哈希表
{
int i,j = 1;
i = hash(e.number);
if(h.elem[i].number == 0){
strcpy(h.elem[i].address,e.address);
strcpy(h.elem[i].name,e.name);
h.elem[i].number = e.number;
}
else{
while(1)
{
if(i + j*j < 20 && i + j*j >= 0){
if(h.elem[i + j*j].number == 0){
strcpy(h.elem[i + j*j].address,e.address);
strcpy(h.elem[i + j*j].name,e.name);
h.elem[i + j*j].number = e.number;
break;
}
else{
if(i - j*j < 20 && i - j*j > 0){
if(h.elem[i - j*j].number == 0){
strcpy(h.elem[i - j*j].address,e.address);
strcpy(h.elem[i - j*j].name,e.name);
h.elem[i - j*j].number = e.number;
break;
}
else{
j++;
continue;
}
}
else{
j++;
continue;
}
}
}
else{
j++;
continue;
}
}
}
}
int searchhash(hashtable h,long long int number,infor &e) //查找号码所对应的信息
{
int i,j = 1;
i = hash(number);
if(h.elem[i].number == number){
strcpy(e.address,h.elem[i].address);
strcpy(e.name,h.elem[i].name);
e.number = h.elem[i].number;
}
else{
while(1)
{
if(i + j*j < 20 && i + j*j >= 0){
if(h.elem[i + j*j].number == number){
strcpy(e.address,h.elem[i + j*j].address);
strcpy(e.name,h.elem[i + j*j].name);
e.number = h.elem[i + j*j].number;
break;
}
else{
if(i - j*j < 20 && i - j*j > 0){
if(h.elem[i - j*j].number == number){
strcpy(e.address,h.elem[i - j*j].address);
strcpy(e.name,h.elem[i - j*j].name);
e.number = h.elem[i - j*j].number;
break;
}
else{
j++;
continue;
}
}
else{
j++;
continue;
}
}
}
else{
j++;
continue;
}
}
}
}
int main()
{
ofstream ofile;
ofile.open("d:\\myfile.txt");
hashtable h;
Inithash(h);
infor e;
while(1){
cout<<"-------------------------------------"<<endl;
cout<<"功能选项:1.录入 2.查找 3.退出"<<endl;
cout<<"-------------------------------------"<<endl;
cout<<"输入功能选项:";
int i;
cin>>i;
if(i == 1){
cout<<"输入电话号码:";
cin>>e.number;
cout<<"输入姓名:";
cin>>e.name;
cout<<"输入地址:";
cin>>e.address;
Inserthash(h,e);
ofile<<e.number<<" "<<e.name<<" "<<e.address<<endl;
}
else if(i == 2){
cout<<"输入待查找号码:";
cin>>e.number;
infor e2;
searchhash(h,e.number,e2);
cout<<"该号码主人姓名:";
cout<<e2.name<<endl;
cout<<"该号码主人住址:";
cout<<e2.address<<endl;
}
else if(i == 3){
cout<<"成功退出系统!";
break;
}
else
cout<<"指令错误!"<<endl;
}
return 0;
}
经验不足,若有不足之处,还望指正包含!!
来源:CSDN
作者:This_pro
链接:https://blog.csdn.net/This_pro/article/details/104077257