数据结构课程设计-哈希表建立职工管理系统
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一.问题描述
职工的姓名通过哈希表建表,基于哈希表的查找,建立一个简单的职工管理
系统。可以利用自己的班集体中的“人名”设计一个哈希表,使得平均查找长度
不超过R,完成相应的建表和查表程序。对将班上同学看做职工进行管理,包括
插入、删除、查找、排序等功能。
二.基本要求
假设人名为中国姓名的汉语拼音形式。待填入哈希表的人名共有30个,取
平均查找长度的上限为2。哈希函数用除留余数法构照,用链表法处理冲突。
职工对象包括姓名、性别、出生年月、工作年月、学历、职务、住址、电话
等信息。
(1)新增一名职工:将新增职工对象按姓名以字典方式职工管理文件中。
(2)删除一名职工:从职工管理文件中删除一名职工对象。
(3)查询:从职工管理文件中查询符合某些条件的职工。
(4)修改:检索某个职工对象,对其某些属性进行修改。
(5)排序:按某种需要对职工对象文件进行排序。
三.数据结构的设计
哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进
行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做哈希表。
1.哈希表的构造方法多种多样,实际工作中需视不同的情况采用不同的哈希
函数,经常在构建一个哈希表选择构造方法时需要考虑的因素有:计算哈希函
数所需时间、关键字的长度、哈希表的大小、关键字的分布情况、记录的查找频
率等。本次题目要求采用除留余数法构造哈希函数,一般方法如下:取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。
即 H(key) = key MOD p,p<=m
不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p
的选择很重要,一般取素数或m,若p选的不好,容易产生同义词。由于职工主
要以姓名为标志,于是将职工姓名的汉语拼音所对应的ASCII码进行相加,所得
到的和作为关键字;取p等于表长30,则关键字除以30以后所得到的余数便是
哈希地址。
2.哈希表是种数据结构,它可以提供快速的插入操作和查找操作。哈希表也
有一些缺点它是基于数组的,数组创建后难于扩展某些哈希表被基本填满时,性
能下降得非常严重。这个问题是哈希表不可避免的,即冲突现象:对不同的关键
字可能得到同一哈希地址。对于如何解决冲突现象,也有喝多方法,本次题目要
求用连地址法处理冲突。一般方法如下:
将所有关键字为同义词的记录存储在同一线性链表中。假设某哈希函数产生
哈希地址的区间在【0,m-1】上,则设立一个指针型变量 Chain ChainHash[m]; 其每个分量的初始状态都是空指针。凡哈希地址为i的记录都插入到头指针为ChainHash[i]的链表中。在链表中的插入位置可以再表头或表尾,也可以再中间,以保持同义词在同一线性链表中按关键字有序。
3.哈希表的查找过程和建表过程基本一致。给定K值,根据建表时设定的哈
希函数求得哈希地址,若表中此位置上没有记录,则查找不成功;否则比较关键字,若何和给定值相等,则查找成功;否则根据建表时设定的处理冲突的方法找“下一地址”,直至哈希表中某个位置为“空”或者表中所填记录飞关键字等于给定值时为止。
五.程序设计思想
根据职工管理系统问题的描述和详细需求分析,要达到上述功能哈希表的数据结构来存储职工信息,并对其进行相应的插入、删除、修改、查询、排序、保存等操作。
(1)输入功能的实现:要想实现职工管理系统的输入,必须要建立一个职工信息系统的抽象数据类型,其中职工信息以哈希表的存储方式实现。
(2)系统处理功能的实现:根据所要进行的操作,在提示信息的提示下,选择相应的服务进行操作。
(3)输出的实现:根据选择的操作,输出与之对应的信息。
综上可以绘制出职工管理问题的系统流程图,如图所示
七.各个模块分析
1.初始化模块:
(1).需求分析
此模块的主要目的是对整个程序进行初始化,即将原有的职工信息从外存全部复制到系统内存中
(2).概要设计
实现方法是:先将职工信息保存到一个txt文件中(即作为外存存储),程序中通过读取文件的方式将这些信息复制到系统内存中,总的说来,就是通过读取文件完成初始化操作。
(3).代码
void InitNameList(){
printf("让我们输入吧!");
ifstream cin("test.txt",ios::in);
if(!cin) {printf("打开失败啦!");return;}
for(int i=0;i cin>>NameList[i].strName>>NameList[i].strSex>>NameList[i].strBirthday>>Name List[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(int i=0;i int j=0; while(NameList[i].strName[j]!='\0'&&j<20){ NameList[i].num+=((int) NameList[i].strName[j]); j++; } } cout< for(int i=0;i cout< "< NameList[i].strBirthday<<" "< "< NameList[i].strPosition<<" "< "< } cout<<"初始化成功!"< system("PAUSE"); } 2.插入模块 (1).需求分析 此模块要求新增一个或多个职工信息到系统中,完成信息的添加工作(2).概要设计 实现方法为:首先建立一个读取结点信息的函数,然后根据信息中的姓名进行关键字的计算,并通过哈希函数求出哈希地址,将此结点的头指针指向哈希地址所对应的链表中,然后将剩余信息通过另一个函数复制到此结点的各个域中,从而完成插入操作 (3).代码 void insert(pName *p){ pName *k; int j=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;