版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
合肥学院计算机科学与技术系课程设计报告2023~2023学年第1学期课程数据结构与算法课程设计名称哈希表实现通讯录学生姓名张宝军学号0604011009专业班级06计科(1)指导教师王昆仑/胡春玲2023年9月题目:〔哈希表的设计与实现的问题〕设计哈希表实现号码查询系统。设计程序完成以下要求:〔1〕设每个记录有以下数据项:号码、用户名、地址;〔2〕从键盘输入各记录,分别以号码和用户名为关键字建立哈希表;〔3〕采用再哈希法解决冲突;〔4〕查找并显示给定号码的记录;〔5〕查找并显示给定用户的记录。一、 问题分析和任务定义此程序需要完成如下要求:设计哈希表实现号码查询系统。实现本程序需要解决以下几个问题:〔1〕 设计结点使该结点包括号码、用户名、地址。〔2〕 利用再哈希法解决冲突。〔3〕 分别以号码和用户名为关键字建立哈希表。〔4〕 实现查找并显示给定号码的记录。〔5〕 查找并显示给定用户的记录。本问题的关键和难点在于如何解决哈希的问题。由于结点的个数无法的知,并且如果采用线性探测法哈希算法,删除结点会引起“信息丧失〞的问题。所以采用链地址法哈希算法。采用拉链法,当出现同义词冲突时,使用链表结构把同义词链接在一起,即同义词的存储地址不是哈希表中其他的空地址。首先,解决的是定义链表结点,在拉链法中,每个结点对应一个链表结点,它由三个域组成,而由于该程序需要分别用号码和用户名为关键字建立哈希表,所以该链表结点它是由四个域组成.name[8]、num[11]和address[20]都是char浮点型,输入输出都只能是浮点型的。采用拉链法,其中的所有同义词构成一个单链表,再由一个表头结点指向这个单链表的第一个结点。这些表头结点组成一个一维数组,即哈希表。数组元素的下标对应由哈希函数求出的哈希地址。其次,设计哈希函数,本程序需要设计两个哈希函数才能解决问题,程序需要分别为以号码和用户名为关键字建立哈希表。所以要分别以用户名、号码为关键字建立两个哈希函数,对于以号码为关键字的哈希函数,是将十一个数字全部相加,然后对20求余。得到的数作为地址。对于以用户名为关键字的哈希函数,是将所有字母的ASCLL码值相加,然后对20求余。再次,需要实现添加结点的功能,那么其中必须包括一个输入结点信息、添加结点的函数;需要实现查找函数,那么必须包括一个查找结点的函数;需要对文件进行保存,那么必需要包括保存文件函数。还需要包括一个主菜单和一个主函数。最后,当程序设计出来后的测试数据为:二、概要设计和数据结构选择在拉链法中,每个结点对应一个链表结点,它由三个域组成,而由于该程序需要分别用号码和用户名为关键字建立哈希表,所以该链表结点它是由四个域组成,链地址法结点结构如图:name[8] num[11] address[20] next其中name[8]和num[11]是分别为以号码和用户名为关键字域,存放关键字;address[20]为结点的数据域,用来存储用户的地址。Next指针是用来指向下一个结点的地址。主要算法的流程图如下:初始化哈希链表〔1〕并为其动态分配内存空间初始化哈希链表〔2〕并为其动态分配内存空间INPUT:开始开始建立新结点temp把temp→next赋为空输入信息结束LIST开始开始i=0i<20p-phone[i]→nextp!=null输入结点信息p=p→next结束i++Hash:开始开始取整型num[i]给key从3开始取i值Num[i]!=0Key=key+(int)num[i]i++Key=key%20结束HASH2:开始开始取整型name[0]给key2从0开始取i值name[i]!=0Key2+=name[i]i++Key2=key2%20结束Apend()开始开始申请新的结点newphonenewnameNewphone=input()Newname指向newphone调用HASH函数调用HASH2函数拉链法处理冲突用户名为关键字输入信息结束Find:开始开始申请新结点q指向phone[key]nextq不为空q=q→nextq不为空输出记录输出结点信息结束调用HASH函数N三、详细设计和编码首先定义结点结构体类型,在拉链法中,每个结点对应一个链表结点,它由三个域组成,而由于该程序需要分别用号码和用户名为关键字建立哈希表,所以该链表结点它是由四个域组成,链地址法结点结构如图:name[8] num[11] address[20] next其中name[8]和num[11]是分别为以号码和用户名为关键字域,存放关键字;address[20]为结点的数据域,用来存储用户的地址。next指针是用来指向下一个结点的地址。#include<fstream>用来输入/输出文件流类包含的文件是fstream。unsignedintkey和unsignedintkey2由于题目要求分别以号码和用户名为关键字,所以在此设计两个关键字。其次,设计两个hash〔〕函数,以号码为关键字建立哈希函数hash(charnum[11])。哈希函数的主旨是将号码的十一位数字全部加起来,然后在对20求余。将计算出来的数作为该结点的地址赋给key。以用户名为关键字建立哈希函数hash2(charname[8])。利用强制类型转换,将用户名的每一个字母的ASCLL码值相加并且除以20后的余数。将计算出来的数作为该结点的地址赋给key2。再次,建立结点,并添加结点,利用拉链法解决冲突。建立结点应包括动态申请内存空间。向结点中输入信息。同时将结点中的next指针等于null。添加结点,首先需要利用哈希函数计算出地址即关键字,其次将该结点插入以关键字为地址的链表后,当然由于分别以用户名和号码为关键字,所以分两种情况,如果以用户名为关键字那么调用voidhash2(charname[8])函数,并且将结点插入对应的哈希链表中,如果以号码为关键字那么调用voidhash(charnum[11])函数,并且将结点插入对应的哈希链表中。并且,需要两个建立哈希链表的函数,分别动态申请一定的空间,用于动态申请哈希链表。voidcreate()用来动态创立以号码为关键字的链表数组,voidcreate2()用来动态创立以用户名为关键字的链表数组。同样,需要两个显示链表的函数,利用for循环和while语句将表中信息按要求输出来。想要实现查找功能,同样需要两个查找函数,无论以用户名还是以号码为关键字,首先,都需要利用hash函数来计算出地址。再依次比照,如果是以号码为关键字,比拟其号码是否相同,如果相同那么输出该结点的所有信息,如果以用户名为关键字,那么比拟用户名是否相同,如果相同那么输出该结点的所有信息。如果找不到与之对应相同的,那么输出“无记录〞。同时需要一个保存文件的函数,利用一个for循环,当用hash函数计算的地址,在链表的动态申请的数组范围之内,那么创立一个文件流对象,并将结点信息保存在该文件中。最后,需要创立一个主菜单和一个主函数,主菜单便于用户的使用,主函数中,包括所有功能对应的数值,使之和主菜单相吻合。当程序设计出来后的测试数据为:可以首先,实现添加结点,将1中的的信息从键盘输入,然后在主菜单中选择保存文件,再将2信息从键盘输入,然后在主菜单中,选择保存文。到此已实现了对信息的储存。可在主菜单中,选择哈希、查找等功能。四、上机调试1、语法错误及修改:由于本算法使用了链表结构和拉链法解决冲突的问题,所以程序可以相对来说得到简化,语句相对简洁。并且冲突得到很好的解决。所以出现的语法问题主要在于子函数和变量的定义,括号的配对,关键字和函数名称的书写,以及一些库函数的标准使用。这些问题均可以根据编译器的警告提示,对应的将其解决。2、逻辑问题修改和调整:链表结构方法虽然方便了运行,但是增加了对算法过程的认识难度。在本程序中每一个函数中都需要涉及到指针的操作。所以需要仔细分析函数中的指针指向。在插入结点,查找结点时尤为突出。对于主菜单和主函数的对应,一定要一致,这样才能保证运行时不会出错。 3、时间,空间性能分析:哈希法本质上是一种通过关键字直接计算存储地址的方法。在理想情况下,哈希函数可以把结点均匀地分布到哈希表中,不发生冲突,那么查找过程无需比拟,其时间复杂度O〔n〕=1。但在实际使用过程中,为了将范围广泛的关键字映射到一组连续的存储空间,往往会发生同义词冲突,这时在查找过程中就需要进行关键字比拟。因此哈希法的查找性能取决于3个因素:哈希函数、冲突处理方法和填充因子。拉链法可以从根本上杜绝二次聚集,从而提高哈希表的均匀度,提高查找性能。当哈希函数和冲突处理方法固定时,哈希法的查找性能就取决于哈希表的填充因子。填充因子a=表中已有的结点数/表的长度。填充因子a标志表的添满程度。很显然,a越小那么发生冲突的时机就越小;反之,a越大冲突的时机就越大,查找的性能也就越低。哈希表链地址法查找成功的平均查找长度SNc=1+a/2。链地址法查找不成功的平均查找长度Un满足:Unc=a+e-a.由以上可以看出,哈希表的平均查找长度是填充因子的函数,和哈希表的长度没有关系,因此在实际应用中,我们应该选择一个适当的填充因子,以便把平均查找长度控制在一个尽量小的范围内。 4、经验和体会:最初拿到这个问题,因为以前在做C++语言课程设计的时候拿到的也是这个题目,所以很熟悉,但是数据结构课上多用的是C,所以用C++来设计并且参考了以前做的题目,联系了数据结构课本上和题目要求做出了设计。刚开始想到的是号码的存储肯定不是固定的一成不变的,所以需要建立动态链表,并且如果采用线性探测法哈希算法解决冲突问题,删除结点会引起“信息丧失〞的问题。因为在线性探测哈希法中,我请教了同学,处理冲突的方式是把同义词放到哈希表中的下一个空地址,而查找是沿着同一个路径进行的。因此当删除了一个结点后,由于标志数组被更新,其后的同义词也将不再被查找到。而采用拉链法,当出现同义词冲突时,使用链表结构把同义词链接在一起,即同义词的存储地址不是哈希表中其他的空地址。因此需要进行详细的分析来发现和解决这些情况。这也是一个对问题从认识到建立模型,之后提出方法,修改方法,最终解决问题的过程。五、使用说明 本程序运行过程时带有提示性语句,由于address[20]、name[8]和num[11]可以看出地址可输入的最大字符数是20,姓名可输入的最大字符数是8,号码都为11位。在输入的时候,用户特别注意号码的位数。实现添加结点,将信息从键盘输入,然后在主菜单中选择保存文件,再将其它信息从键盘输入,然后在主菜单中,选择保存文。到此已实现了对信息的储存。可在主菜单中,选择哈希、查找等功能。六、测试结果主截面:输入并存储结点信息:按姓名查找:按查找:退出:七、参考书目2007年6月第一版王昆仑李红《数据结构与算法》中国铁道出版社2007年5月第十五次版郑莉董渊张瑞丰C++语言程序设计〔第3版〕八、附录#include<iostream>#include<string>#include<fstream>usingnamespacestd;#defineNULL0unsignedintkey;//用来输入/输出文件流类unsignedintkey2;//key和key2分别是用做了号码和姓名的关键字int*p;structnode//新建节点〔用户姓名、地址、号码、指向下一个结点的指针〕{charname[8],address[20];charnum[11];node*next;};typedefnode*pnode;typedefnode*mingzi;//声明了名字和两个指针node**phone;node**nam;node*a;voidhash(charnum[11])//以号码为关键字建立哈希函数{inti=3;key=(int)num[2];while(num[i]!=NULL){key+=(int)num[i];i++;}key=key%20;}voidhash2(charname[8])//姓名为关键字建立哈希函数{inti=1;key2=(int)name[0];while(name[i]!=NULL){key2+=(int)name[i];i++;}key2=key2%20;}//强制类型转换,将用户名的每一个字母的ASCLL码值相加并且除以20后的余数node*input()//输入节点信息,建立结点,并将结点的next指针指空{node*temp;temp=newnode;temp->next=NULL;cout<<"输入姓名:"<<endl;cin>>temp->name;cout<<"输入地址:"<<endl;cin>>temp->address;cout<<"输入:"<<endl;cin>>temp->num;returntemp;}//对于指针类型返回的是地址intapend()//添加节点{node*newphone;node*newname;newphone=input();newname=newphone;newphone->next=NULL;newname->next=NULL;hash(newphone->num);//利用哈希函数计算出对应关键字的存储地址hash2(newname->name);newphone->next=phone[key]->next;//利用号码为关键字插入phone[key]->next=newphone;//是采用链地址法,拉链法处理冲突的哈希表结构newname->next=nam[key2]->next;//利用用户名为关键字插入nam[key2]->next=newname;return0;}voidcreate()//新建节点{inti;phone=newpnode[20];//动态创立对象数组,C++课本P188页for(i=0;i<20;i++){phone[i]=newnode;phone[i]->next=NULL;}}voidcreate2()//新建节点{inti;nam=newmingzi[20];for(i=0;i<20;i++){nam[i]=newnode;nam[i]->next=NULL;}}voidlist()//显示列表{inti;node*p;for(i=0;i<20;i++){p=phone[i]->next;while(p){cout<<p->name<<'_'<<p->address<<'_'<<p->num<<endl;p=p->next;}}}voidlist2()//显示列表{inti;node*p;for(i=0;i<20;i++){p=nam[i]->next;while(p){cout<<p->name<<'_'<<p->address<<'_'<<p->num<<endl;p=p->next;}}}voidfind(charnum[11])//在以号码为关键字的哈希表中查找用户信息{hash(num);node*q=phone[key]->next;while(q!=NULL){if(strcmp(num,q->num)==0)break;q=q->next;}if(q)cout<<q->name<<"_"<<q->address<<"_"<<q->num<<endl;elsecout<<"无此记录"<<endl;}voidfind2(charname[8])//在以用户名为关键字的哈希表中查找用户信息{hash2(name);node*q=nam[key2]->next;while(q!=NULL){if(strcmp(name,q->name)==0)break;q=q->next;}if(q)cout<<q->name<<"_"<<q->address<<"_"<<q->num<<endl;elsecout<<"无此记录"<<endl;}voidsave()//保存用户信息{inti;node*p;for(i=0;i<20;i++){p=phone[i]->next;while(p){fstreamiiout("out.txt",ios::out);//创立一个文件流对象:iioutiiout<<p->name<<"_"<<p->address<<"_"<<p->num<<endl;//将信息存如文件p=p->next;}}}voidmenu()//菜单{cout<<"哈希表通讯录"<<endl;cout<<"0.添加记录"<<endl;cout<<"2.姓名哈希"<<endl;cout<<"3.查找记录"<<endl;co
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- (新)部编版三年级上册语文七篇阅读训练试题及答案
- 妇产科操作相关医疗纠纷防范策略
- 头颈癌放疗后靶向免疫联合策略
- 多重用药下康复方案的调整原则
- 德国考试题及答案
- 2025年大学艺术设计(设计创作)试题及答案
- 多组学技术在精准医疗中的精准度提升策略
- 多组学分析指导的肿瘤症状精准支持策略-1
- 2025年中职(粉末冶金技术)粉末压制工艺专项测试试题及答案
- 2026年家政服务(卫生间清洁)试题及答案
- 2026年初二物理寒假作业(1.31-3.1)
- 2025秋人教版七年级上册音乐期末测试卷(三套含答案)
- 2025福建德化闽投抽水蓄能有限公司招聘4人(公共基础知识)综合能力测试题附答案
- “十五五规划纲要”解读:和美乡村宜居宜业
- 广东省广州市2026届高三年级上学期12月调研测试数学(广州零模)(含答案)
- 2025-2030中国工业硅行业市场现状供需分析及投资评估规划分析研究报告
- 手机供货协议书
- 2025年北京高中合格考政治(第二次)试题和答案
- 民俗的特征教学课件
- 山东省潍坊市2023-2024学年高一上学期期末考试地理试题(含答案)
- 设计素描教案
评论
0/150
提交评论