《数据结构》课程设计
哈希表实现电话号码查询系统
一目的
利用《数据结构》课程的相关知识完成一个具有一定难度的综合设计题目,利用C/C++语言进行程序设计,并规范地完成课程设计报告。通过课程设计,巩固和加深对线性表、栈、队列、字符串、树、图、查找、排序等理论知识的理解;掌握现实复杂问题的分析建模和解决方法(包括问题描述、系统分析、设计建模、代码实现、结果分析等);提高利用计算机分析解决综合性实际问题的基本能力。
二需求分析
1、程序的功能
1) 读取数据
① 读取原电话本存储的电话信息。
② 读取系统随机新建电话本存储的电话信息。 2) 查找信息
① 根据电话号码查询用户信息。 ② 根据姓名查询用户信息。 3) 存储信息
查询无记录的结果存入记录文档。
2、输出形式
1) 数据文件“old.txt”存放原始电话号码数据。
2) 数据文件“new.txt”存放有系统随机生成的电话号码文件。 3) 数据文件“out.txt”存放未查找到的电话信息。 4) 查找到相关信息时显示姓名、地址、电话号码。
3、初步测试计划
1) 从数据文件“old.txt”中读入各项记录,或由系统随机产生各记录,并且把记录保存到“new.txt”中 。
2) 分别采用伪随机探测再散列法和再哈希法解决冲突。 3) 根据姓名查找时显示给定姓名用户的记录。 4) 根据电话号码查找时显示给定电话号码的用户记录。
xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 1
《数据结构》课程设计
5) 将没有查找的结果保存到结果文件Out.txt中。
6) 系统以菜单界面工作,运行界面友好,演示程序以用户和计算机的对话方式进行。
三概要设计
1、子函数功能
int Collision_Random(int key,int i) //伪随机数探量观测再散列法处理冲突
void Init_HashTable_by_name(string name,string phone,string addre) //以姓名为关键字建立哈希表
int Collision_Rehash(int key,string str) //再哈希法处理冲突
void Init_HashTable_by_phone(string name,string phone,string addre) //以电话号码为关键字建立哈希表 void Outfile(string name,int key) //在没有找到时输出未找到的记录,打开文件out.txt并将记录储存在文档中 void Outhash(int key) //输出哈希表中的记录 void Rafile() //随机生成数据,并将数据保存在new.txt void Init_HashTable(char*fname,int n) //建立哈希表
int Search_by_name(string name) //根据姓名查找哈希表中的记录 int Search_by_phone(string phone) //根据电话号码查找哈希表中的记录
xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 2
《数据结构》课程设计
2、函数调用图
main()Refile()init-hashtable()init-hashtable-by-name()init-hashtable-by-phone()Seach-by-name()Seach-by-phone()Coiiision-random()Collision-rehash()Outhash()xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 3
《数据结构》课程设计
四详细设计
1、主函数流程图
开始选择数据来源21建“new.txt”选择查找方式12姓名查找电话号码查找12021输入姓名显示哈希表0显示哈希表输入电话号码无此记录显示信息无此记录显示信息0写入“out.txt”写入“out.txt”结束
2、“伪随机探测再散列处理冲突”伪代码
若对应位置上已经存在其他数据,则新的关键字=(原关键字+伪随机数)%哈希表长。 若新的位置上也存在其他数据,则用伪随机序列的下一个数求新的关键字,直到找到合适的位置。
3、“再哈希法处理冲突”伪代码
用“折叠法”将电话号码的ASCII码值定义为关键字,分别为前四位、中四位、后三位。
再用“除留余数法”求的新的关键字=原关键字%哈希表长。
xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6
《数据结构》课程设计
4、“以姓名为关键字建立哈希表”伪代码
用“除留余数法”将姓名的ASCII码值定义为关键字。
若对应位置上存在其他数据,则调用伪随机处理冲突,然后将数据存入哈希表。
5、“以电话号码为关键字建立哈希表”伪代码
用“除留余数法”将电话号码的ASCII码值定义为关键字。 若对应位置上存在其他数据,则调用再哈希处理冲突。 然后将数据存入哈希表。
五调试分析
1、程序的关键是掌握文件的相关操作、哈希函数的创建和运用、伪随机法处理冲突、再哈希法处理冲突等。在编程的过程中,出现了很多问题,如文件无法正常打开、程序进入死循环、无法实现文件的写入操作、忘了添加头文件等错误。修改后程序运行正确。
2、创建“new.txt”内容用子函数来实现,但是原数据是从“old.txt”文件中读取的,刚开始不知道怎样实现二者之间的选择,在同学和参考书的帮助下终于得到解决。
3、关于伪随机和再哈希的相关内容觉得很难懂,看了很久参考书才有所了解
六测试结果
1、根据姓名查找
1) 姓名查找成功
2) 姓名查找失败
xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 5
《数据结构》课程设计
3) 哈希表
xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 6
《数据结构》课程设计
2、根据电话号码查找
1) 电话号码输入错误
xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 7
《数据结构》课程设计
2) 电话号码查询成功
3) 电话号码查询失败
xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 8
《数据结构》课程设计
4) 哈希表
xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 9
《数据结构》课程设计
七用户使用说明
1、选择数据来源
根据提示信息进行操作,选择已存在的“old.txt”文件中的数据或系统当前自动生成的“new.txt”文件。
xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 10
《数据结构》课程设计
2、选择查找方式
根据提示信息进行操作,选择“根据姓名查找”或“根据电话号码查找”两种查找方式。
3、选择功能
根据提示信息进行操作,选择输入已知信息或查看哈希表。
xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 11
《数据结构》课程设计
4、显示结果
xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6
《数据结构》课程设计
xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 13
《数据结构》课程设计
xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 14
《数据结构》课程设计
5、查看文件
xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 15
《数据结构》课程设计
八课程设计总结
1、收获
学会了C++的跟踪。更进一步了解和熟悉了关于哈希表的运用和文件的读取与写入操作。同时锻炼了对话形式的菜单的创建和熟练运用。
2、心得体会
在这次数据结构设计中遇到了很多实际性的问题,在实际设计中才发现,书本上理论性的东西与在实际运用中的还是有一定的出入的,所以有些问题要不断地更正以前的错误思维。通过这次设计,我懂得了学习的重要性,了解到理论知识与实践相结合的重要意义,xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 16
《数据结构》课程设计
学会了坚持、耐心和努力,这将为自己今后的学习和工作做出了最好的榜样。我觉得作为一名计科专业的学生,这次课程设计是很有意义的。更重要的是如何把自己平时所学的东西应用到实际中。虽然自己对于这门课懂的并不多,很多基础的东西都还没有很好的掌握,觉得很难,也没有很有效的办法通过自身去理解,但是靠着学习,渐渐对这门课逐渐产生了些许的兴趣,自己开始主动学习并逐步从基础慢慢开始弄懂它。
xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6
《数据结构》课程设计
附录:源程序
#include #include #include
using namespace std;
ifstream in_file; ofstream out_file;
int D[10]={1,3,5,8,13,15,17,21,27,34};//伪随机数序列 int count;//当前数据元素个数 int sizeindex;//哈希表的长度 char *sign;//冲突的标志
struct Data { string name; string phone; string addre; }; Data *intermediate_data;
int Collision_Random(int key,int i)//伪随机数探量观测再散列法处理冲突{ int Re_key; if(sign[key]==\'1\') { xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 18
《数据结构》课程设计
} Re_key=(key+D[i])%sizeindex; return Re_key;//归回新的要害码
return -1; }
void Init_HashTable_by_name(string name,string phone,string addre)//以姓名为关键字建立哈希表
{ int i=0; int key; char*p; for(key=0,p=&name[0];*p;p++) key=key+*p; key=key%42; while(sign[key]==\'1\') {
} if(key==-1) exit(1); key=Collision_Random(key,i+1); count++; intermediate_data[key].name=name;//将数据存入哈希表
intermediate_data[key].addre=addre; intermediate_data[key].phone=phone; sign[key]=\'1\';//设置冲突标志 }
xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 19
《数据结构》课程设计
int Collision_Rehash(int key,string str)//再哈希法处理冲突 { int Re_key; int num1=(str[0]-\'0\')*1000+(str[1]-\'0\')*100+(str[2]-\'0\')*10+(str[3]-\'0\'); int num2=(str[4]-\'0\')*1000+(str[5]-\'0\')*100+(str[6]-\'0\')*10+(str[7]-\'0\'); int num3=(str[8]-\'0\')*100+(str[9]-\'0\')*10+(str[10]-\'0\'); Re_key=num1+num2+num3; Re_key=(Re_key+key)%sizeindex; return Re_key; }
void Init_HashTable_by_phone(string name,string phone,string addre)//以电话号码为关键字建立哈希表
{ int key; char*p; for(key=0,p=&phone[0];*p;p++) key=key+*p; key=key%42; while(sign[key]==\'1\') {
} count++; intermediate_data[key].name=name; intermediate_data[key].addre=addre; intermediate_data[key].phone=phone; key=Collision_Rehash(key,phone); xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 20
《数据结构》课程设计
sign[key]=\'1\'; }
void Outfile(string name,int key)//在没有找到时输出未找到的记录,打开文件out.txt并将记录储存在文档中
{ if((key==-1)||(sign[key]==\'0\')) {
out_file.open(\"out.txt\");
if(out_file.fail())
{
cout
exit(1);
}
out_file
out_file.close(); } }
void Outhash(int key)//输出哈希表中的记录 { unsigned i; if((key==-1)||(sign[key]==\'0\')) {
cout
} else xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 21
《数据结构》课程设计
{
for(i=0;i
cout
for(i=0;i
cout
cout
for(i=0;i
cout
cout
void Rafile()//随机生成数据,并将数据保存在new.txt { int i,j; out_file.open(\"new.txt\"); if(out_file.fail()) {
cout
exit(1); } for(j=0;j
string name=\"\";
for(i=0;i
name+=rand()%26+\'a\'; out_file
《数据结构》课程设计
string phone=\"\";
for(i=0;i
phone+=rand()%10+\'0\';
out_file
string addre=\"\";
for(i=0;i
addre+=rand()%26+\'a\';
addre+=\',\';
out_file
void Init_HashTable(char*fname,int n)//建立哈希表{ string name=\"\"; string phone=\"\"; string addre=\"\"; int i,j; in_file.open(fname); if(in_file.fail()) {
cout
exit(1); } while(!in_file.eof()) { xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 23
《数据结构》课程设计
字
键字
} char* str=new char[100]; name=\"\"; phone=\"\"; addre=\"\"; in_file.getline(str,100,\'\\n\');//按行读入数据 if(str[0]==\'*\')//判断数据结束
i=0; while(str[i]=122) i++; break; for(;str[i]!=\' \';i++) name+=str[i]; while(str[i]==\' \') i++; for(j=0;str[i]!=\' \';j++,i++) phone+=str[i]; while(str[i]==\' \') i++; for(j=0;str[i]!=\',\';j++,i++) addre+=str[i]; if(n==1) Init_HashTable_by_name(name,phone,addre);//以姓名为关键else Init_HashTable_by_phone(name,phone,addre);//以电话号码为关delete str; in_file.close(); }
xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6
24
《数据结构》课程设计
int Search_by_name(string name)//根据姓名查找哈希表中的记录 { int i=0;int j=1; int key; char*p; for(key=0,p=&name[0];*p;p++) key=key+*p; key=key%42; while(sign[key]==\'1\'&&(intermediate_data[key].name!=name)) {
key=Collision_Random(key,i+1);
j++;
if(j=count)
return -1; } return key; }
int Search_by_phone(string phone)//根据电话号码查找哈希表中的记录{ int key; char*p; for(key=0,p=&phone[0];*p;p++) key=key+*p; key=key%42; int j=1; xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 25
《数据结构》课程设计
while(sign[key]==\'1\'&&(intermediate_data[key].phone!=phone)) {
key=Collision_Rehash(key,phone);
j++;
if(j=count)
return-1; } return key; }
void main() { count=0; sizeindex=50; int i,k; int ch; char *Fname;
sign=new char[sizeindex];
intermediate_data=new Data[sizeindex];
for(i=0;i
for(i=0;i
《数据结构》课程设计
{
}
cout
*§\"
*§\"
*§\"
*§\"
*§\"
*§\"
cout
do {
switch(k) cout>k; cout
《数据结构》课程设计
{
case 0:
return; case 1:
Fname=\"old.txt\"; break; case 2:
Rafile(); Fname=\"new.txt\"; break; default:
} while((k!=1)&&(k!=2)&&(k!=0));
//system(\"cls\");
cout
*§\"
*§\"
*§\"
*§\"
*§\"
cout
《数据结构》课程设计
*§\"
cout
//system(\"cls\");
endl;
*§\"
}
while((ch!=1)&&(ch!=2)); cout>ch; if(ch!=1&&ch!=2) { }
cout
《数据结构》课程设计
*§\"
cout
*§\"
*§\"
*§\"
*§\"
cout
do {
cout
cin>>choice; cout
switch(choice) {
case 1: {
int key1; string name;
cout
cin>>name;
key1=Search_by_name(name); xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 30
《数据结构》课程设计
Outfile(name,key1); cout
Outhash(key1);
}
break;
case 2:
{ cout
for(i=0;i
{
if(sign[i]!=\'0\')
{
cout
Outhash(i);
}
}
cout
}
break;
case 0:
return; default: xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 31
《数据结构》课程设计
cout
endl;
*§\"
*§\"
*§\"
*§\"
*§\"
*§\"
cout
cout
32
} } } while((choice!=1)&&(choice!=2)&&(choice!=0));
while(ch==2) { int choice;
cout
cout
cout
cout
cout
do { xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6
《数据结构》课程设计
cin>>choice;
switch(choice)
{
case 1:
{
int key2;
string phone; do
{
cout
的电话号码: \";
cin>>phone;
if(strlen(&phone[0])!=11)
{
cout
key2=Search_by_phone(phone); Outfile(phone,key2);
}
while(strlen(&phone[0])!=11); cout
cout
33 xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6
《数据结构》课程设计
Outhash(key2);
}
break;
case 2:
{ cout
for(i=0;i
{
if(sign[i]!=\'0\')
{
cout
Outhash(i);
}
}
cout
}
break;
case 0:
return;
default:
cout
34
《数据结构》课程设计
}
while((choice!=1)&&(choice!=2)&&(choice!=0));
}
} xxxx大学xxxx学院xxxx专业学号:xxxxxxx姓名:jenery6 35