数据结构课程设计哈希表建立职工管理系统.docx
- 文档编号:30505752
- 上传时间:2023-08-16
- 格式:DOCX
- 页数:25
- 大小:273.40KB
数据结构课程设计哈希表建立职工管理系统.docx
《数据结构课程设计哈希表建立职工管理系统.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计哈希表建立职工管理系统.docx(25页珍藏版)》请在冰豆网上搜索。
数据结构课程设计哈希表建立职工管理系统
一.问题描述
职工的姓名通过哈希表建表,基于哈希表的查找,建立一个简单的职工管理系统。
可以利用自己的班集体中的“人名”设计一个哈希表,使得平均查找长度不超过R,完成相应的建表和查表程序。
对将班上同学看做职工进行管理,包括插入、删除、查找、排序等功能。
二.基本要求
假设人名为中国姓名的汉语拼音形式。
待填入哈希表的人名共有30个,取平均查找长度的上限为2。
哈希函数用除留余数法构照,用链表法处理冲突。
职工对象包括姓名、性别、出生年月、工作年月、学历、职务、住址、电话等信息。
(1)新增一名职工:
将新增职工对象按姓名以字典方式职工管理文件中。
(2)删除一名职工:
从职工管理文件中删除一名职工对象。
(3)查询:
从职工管理文件中查询符合某些条件的职工。
(4)修改:
检索某个职工对象,对其某些属性进行修改。
(5)排序:
按某种需要对职工对象文件进行排序。
三.数据结构的设计
哈希表(Hashtable,也叫散列表),是根据关键码值(Keyvalue)而直接进行访问的数据结构。
也就是说,它通过把关键码值映射到表中一个位置来访问记录,加快查找的速度。
这个映射函数叫做散列函数,存放记录的数组叫做哈希表。
1.哈希表的构造方法多种多样,实际工作中需视不同的情况采用不同的哈希函数,经常在构建一个哈希表选择构造方法时需要考虑的因素有:
计算哈希函数所需时间、关键字的长度、哈希表的大小、关键字的分布情况、记录的查找频率等。
本次题目要求采用除留余数法构造哈希函数,一般方法如下:
取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。
即H(key)=keyMODp,p<=m
不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。
对p的选择很重要,一般取素数或m,若p选的不好,容易产生同义词。
由于职工主要以姓名为标志,于是将职工姓名的汉语拼音所对应的ASCII码进行相加,所得到的和作为关键字;取p等于表长30,则关键字除以30以后所得到的余数便是哈希地址。
2.哈希表是种数据结构,它可以提供快速的插入操作和查找操作。
哈希表也有一些缺点它是基于数组的,数组创建后难于扩展某些哈希表被基本填满时,性能下降得非常严重。
这个问题是哈希表不可避免的,即冲突现象:
对不同的关键字可能得到同一哈希地址。
对于如何解决冲突现象,也有喝多方法,本次题目要求用连地址法处理冲突。
一般方法如下:
将所有关键字为同义词的记录存储在同一线性链表中。
假设某哈希函数产生哈希地址的区间在【0,m-1】上,则设立一个指针型变量ChainChainHash[m];其每个分量的初始状态都是空指针。
凡哈希地址为i的记录都插入到头指针为ChainHash[i]的链表中。
在链表中的插入位置可以再表头或表尾,也可以再中间,以保持同义词在同一线性链表中按关键字有序。
3.哈希表的查找过程和建表过程基本一致。
给定K值,根据建表时设定的哈希函数求得哈希地址,若表中此位置上没有记录,则查找不成功;否则比较关键字,若何和给定值相等,则查找成功;否则根据建表时设定的处理冲突的方法找“下一地址”,直至哈希表中某个位置为“空”或者表中所填记录飞关键字等于给定值时为止。
四
.程序流程图
YN
五.程序设计思想
根据职工管理系统问题的描述和详细需求分析,要达到上述功能哈希表的数据结构来存储职工信息,并对其进行相应的插入、删除、修改、查询、排序、保存等操作。
(1)输入功能的实现:
要想实现职工管理系统的输入,必须要建立一个职工信息系统的抽象数据类型,其中职工信息以哈希表的存储方式实现。
(2)系统处理功能的实现:
根据所要进行的操作,在提示信息的提示下,选择相应的服务进行操作。
(3)输出的实现:
根据选择的操作,输出与之对应的信息。
综上可以绘制出职工管理问题的系统流程图,如图所示
七.各个模块分析
1.初始化模块:
(1).需求分析
此模块的主要目的是对整个程序进行初始化,即将原有的职工信息从外存全部复制到系统内存中
(2).概要设计
实现方法是:
先将职工信息保存到一个txt文件中(即作为外存存储),程序中通过读取文件的方式将这些信息复制到系统内存中,总的说来,就是通过读取文件完成初始化操作。
(3).代码
voidInitNameList(){
printf("让我们输入吧!
");
ifstreamcin("test.txt",ios:
:
in);
if(!
cin){printf("打开失败啦!
");return;}
for(inti=0;i cin>>NameList[i].strName>>NameList[i].strSex>>NameList[i].strBirthday>>NameList[i].strWorkage>>NameList[i].strXueli>>\ NameList[i].strPosition>>NameList[i].strAddress>>NameList[i].strPhone; NameList[i].num=0; NameList[i].next=NULL; //if(i)NameList[i-1].next=&NameList[i]; } for(inti=0;i intj=0; while(NameList[i].strName[j]! ='\0'&&j<20){ NameList[i].num+=((int)NameList[i].strName[j]); j++; } } cout< for(inti=0;i cout< NameList[i].strBirthday<<""< NameList[i].strPosition<<""< } cout<<"初始化成功! "< system("PAUSE"); } 2.插入模块 (1).需求分析 此模块要求新增一个或多个职工信息到系统中,完成信息的添加工作 (2).概要设计 实现方法为: 首先建立一个读取结点信息的函数,然后根据信息中的姓名进行关键字的计算,并通过哈希函数求出哈希地址,将此结点的头指针指向哈希地址所对应的链表中,然后将剩余信息通过另一个函数复制到此结点的各个域中,从而完成插入操作 (3).代码 voidinsert(pName*p){ pName*k; intj=0; while(p->strName[j]! ='\0'&&j<20){ p->num+=((int)p->strName[j]); j++; } k=HashList[p->num%M].next; if(k){ while(k->next)k=k->next; k->next=p; } else HashList[p->num%M].next=p; k=HashList[p->num%M].next; while(k->next)k=k->next; } voidInsert(){ printf("让我们输入要新建的人吧! "); pName*p=newpName,*k; printf("输入: 拼音性别出生年月工作年月学历职位地址电话\n"); cin>>p->strName>>p->strSex>>p->strBirthday>>p->strWorkage>>p->strXueli>>p->strPosition>>p->strAddress>>p->strPhone; p->next=NULL;p->num=0; insert(p); printf("插入成功! "); system("PAUSE"); } 3.删除模块 (1).需求分析 此模块要求能从系统内存中读取职工信息,并将其删除 (2).概要设计 实现方法: 首先输入要删除职工的姓名,然后进行关键字运算以及求解哈希地址,找到该职工所对应的链表区域,并将其信息显示出来;然后将其上一个结点的指针指向它的下一个结点,完成删除任务 (3).代码 voidDelete(){ cout<<"请输入你要删掉的人吧! "; charname[20]; cin>>name; intj=0,count=0; while(name[j]! ='\0'&&j<20){ count+=((int)name[j]); j++; } intid=count%M; pName*p=HashList[id].next,*k; cout< if(! p){cout<<"Oops,没有这个人哦.\n";return;} k=p; intcheck=1; while(p){ if(! strcmp(p->strName,name)){ cout<<"找到啦! 这个家伙的信息: "< printf("拼音性别出生年月工作年月学历职位地址电话\n"); cout< check=0; break; } k=p; p=p->next; } if(check){cout<<"哦哟,没有这个人哦."< cout<<"让我们删了他吧! "< if(HashList[id].next==p)HashList[id].next=p->next; else k->next=p->next; cout<<"删除成功! "< } 4.查找模块 (1).需求分析 此模块需要通过接受输入的姓名,完成对该姓名在哈希表中的查找工作,并将其信息显示出来 (2).概要设计 实现方法是: 首先输入要查找职工的姓名,然后进行关键字运算以及求解哈希地址,找到该职工所对应的链表的头结点位置,然后循环此头结点所对应单链表,找出与输入姓名相同的职工信息,并将其显示出来 (3).代码 voidSearchList() { system("cls"); char*f; printf("\n\n请输入你要查找的姓名(拼音)");/*输入姓名*/ charname[20]; scanf("%s",name); f=name; ints=0,r; for(r=0;*(f+r)! ='\0';r++)/*求出姓名的拼音所对应的整数也就是关键字*/ { s+=(int)*(f+r);/*利用字符与整数的自动转换相加字符的ASCII码*/ } intadr=s%M;/*使用哈希函数*/ if(HashList[adr].next==NULL)/*通过指针的指向判断一个单链表中是否存在要查找的数*/ {printf("无该记录"); } else {if((HashList[adr].next)->next==NULL) {if(HashList[adr].next->num==s) {inti=1; printf("\n姓名: %s",(HashList[adr].next)->strName); printf("\n性别: %s",(HashList[adr].next)->strSex); printf("\n出生年月: %s",(HashList[adr].next)->strBirthday); printf("\n工作年月: %s",(HashList[adr].next)->strWorkage); printf("\n学历: %s",(HashList[adr].next)->strXueli); printf("\n职位: %s",(HashList[adr].next)->strPosition); printf("\n地址: %s",(HashList[adr].next)->strAddress); printf("\n电话: %s",(HashList[adr].next)->strPhone); printf("\n关键字: %d",(HashList[adr].next)->num); printf("\n查找长度: %d\n",i); } } else { pName*m; inti=1; m=HashList[adr].next; while(m->next! =NULL)/*循环该单链表查找出你所要查找的数据并把他们输出*/ { if(m->num==s) {printf("\n姓名: %s",m->strName); printf("\n性别: %s",m->strSex); printf("\n出生年月: %s",m->strBirthday); printf("\n工作年月: %s",m->strWorkage); printf("\n学历: %s",m->strXueli); printf("\n职位: %s",m->strPosition); printf("\n地址: %s",m->strAddress); printf("\n电话: %s",m->strPhone); printf("\n关键字: %d",m->num); printf("查找长度: %d",i); break; } m=m->next; i++; } } } system("PAUSE"); } 5.排序模块 (1).需求分析 此模块要求按某种需要对哈希表中的信息进行排序,此处选用一种简单的排序方法: 姓名的第一个拼音在22个字母表中的位置进行排序,剩下的字母不参加排序 (2).概要设计 实现方法是: 对姓名汉语拼音的首字母按字母表顺序进行排序,只需完成首字母的比较即可 (3).代码 voidsort() { cout<<"我们按名字的第一个拼音在22个字母表中的位置进行排序,剩下的字母不参加排序"< printf("拼音性别出生年月工作年月学历职位地址电话\n"); pName*p; for(intj='a';j<='z';j++) for(inti=0;i p=HashList[i].next; while(p){ if(p->strName[0]==j) cout< < p=p->next; } } system("PAUSE"); } 6.显示哈希表模块 (1).需求分析 此模块需要完成对整个哈希表的显示,除了每个职工的基本信息外,还应包含该职工的哈希地址 (2).概要设计 实现方法是: 用下标地址代表哈希地址,哈希地址的算法同上,在整个哈希表内,将哈希地址连同职工信息一起输出 (3).代码 voidDisplay() {system("cls"); printf("下标地址关键字拼音性别出生年月工作年月学历职位地址电话\n");/*显示的格式*/ pName*k; for(inti=0;i k=HashList[i].next; while(k){ printf("%d",i); printf("%s",k->strName); printf("%s",k->strSex); printf("%s",k->strBirthday); printf("%s",k->strWorkage); printf("%s",k->strXueli); printf("%s",k->strPosition); printf("%s",k->strAddress); printf("%s",k->strPhone); printf("\n"); k=k->next; } } system("PAUSE"); } 7.修改模块 (1)需求分析 此模块要求可以对哈希表中的职工信息进行修改 (2).概要设计 实现方法是: 先通过输入的姓名进行查找工作,将其显示出来,然后对该信息进行删除操作,只不过此处的删除操作只删除信息域,不删除结点,接下来立刻将修改后的信息填入该空结点中,继而完成修改工作 (3).代码 voidChange(){ cout<<"请输入你要改变的人吧! \n"; charname[20]; cin>>name; intj=0,count=0; while(name[j]! ='\0'&&j<20){ count+=((int)name[j]); j++; } intid=count%M; pName*p=HashList[id].next,*k; cout< if(! p){cout<<"Oops,没有这个人哦.\n"; system("PAUSE");return;} k=p; intcheck=1; while(p){ if(! strcmp(p->strName,name)){ cout<<"找到啦! 这个家伙的信息: \n"< printf("拼音性别出生年月工作年月学历职位地址电话\n"); cout< check=0; break; } k=p; p=p->next; } if(check){cout<<"哦哟,没有这个人哦.\n"< cout<<"\n让我们改了他吧! \n"< if(HashList[id].next==p)HashList[id].next=p->next; else k->next=p->next; printf("输入: 拼音性别出生年月工作年月学历职位地址电话\n"); cin>>p->strName>>p->strSex>>p->strBirthday>>p->strWorkage>>p->strXueli>>p->strPosition>>p->strAddress>>p->strPhone; p->next=NULL;p->num=0; insert(p); cout<<"修改成功! "< system("PAUSE"); } 八.调试分析、测试数据 1.初始化模块 2.插入模块 3.删除模块 4.查找模块 5.排序模块 6.显示模块 7.修改模块 八.心得体会 1.收获 此次数据结构课程设计差不多用了一周的时间,真正的投入了进去,自然我也得到了很多收获。 对于学习知识这一块,这次真学了不少,恶补了很多知识。 以前编程能力很差,根本不知道如何让下手,可是这次的课程设计我抱着挑战自己的心态,没想到完成的这么好,增加了自己对编程的信心。 很多以前不知道的基本的编程方法或者一些常用固定的模式,我都在这次设计中学会了,总的说来,对我的编程能力有了很大提升。 此次是两个人一组完成任务,在这个过程中我也体会到了合作的力量,我们分工协作,有不懂的地方就大家一起讨论,仍然不能解决的问题就请教其他同学或者老师。 最后,我们也配合得很好 2.遇到的困难 此次课程设计中,我们也遇到了很多困难。 由于哈希表没学,所以我们只有自学,当然会有一些不懂的地方,这也就免不了请教老师。 对于这个题目的设计,我们也遇到了一些困难。 例如: (1)利用除留余数法建立哈希表时,除数p的选择是一个关键,一旦选择的不好会大大影响哈希表的性能,起初看书也没有解决这个问题,后来实在网上查阅了一些资料才解决; (2)由于哈希表是由外部文件进行初始化后得到的,所以在插入操作时,如何能将信息插入到外部的文件中是一个很棘手的问题,最后,我们没能实现这个问题,只是在内存中插入了信息; (3)排序模块也是一个比较麻烦的事情,因为我们认为哈希表本来就是一个排序了的程序(根据哈希地址),所以一直不能理解这个排序的意思,最后没有办法,就对姓名作了一下简单的排序。 3.对本次课程设计提出改进的地方 (1)初始化操作读取文件时,可以用即可以读出又可以写入的文件方式,可以解决插入信息不能反馈到外存中的问题。 (2)可以再建一个利用其他信息作为关键字的哈希表,这样在查找信息是可以多一种查找方式,使系统更完善。 (3)修改模块中,可以不用整个结点信息删除然后再填入新信息的方式,利用链表数据域的特点,实现对其中某个信息的修改,则可以不用又将不需要改变的信息输入一遍,操作起来方便,而且性能也会更好。 4.对数据结构这门课的认识 编写程序的语言有很多种,以前我们学过C语言,但是这次课程设计运用数据结构编写程序让我感觉到更简单,以前要用很多C语句的程序,只要选对了数据结构,编写起来会很简单。 这也是我对数据结构这门课重要性和实用性的认识。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 哈希表 建立 职工 管理 系统