当前位置:文档之家› 课程设计试验报告-哈希表的设计与实现

课程设计试验报告-哈希表的设计与实现

数据结构课程设计题目哈希表的设计与实现作者院系信息工程学院专业信息管理与信息系统学号1514210117指导老师张慧答辩时间2016年12月18日目录数据结构课程设计 01系统需求分析 (1)1.1用户需求分析 (2)1.2功能需求分析 (2)1.3数据需求分析 (3)1.4 小结 (3)2系统设计 (4)2.1设计内容及要求 (4)2.2总体设计思路 (4)2.3程序详细设计流程图 (5)2.31以姓名为关键字的Hash()函数流程图 (5)2.32添加结点信息流程图: (6)1-2添加结点信息流程图: (7)2.33按姓名查找流程图: (7)2.34按号码查找流程图 (8)2.35主程序流程图 (8)2.4详细设计编码 (10)2.41建立节点 (10)2.42对哈希函数的定义 (10)2.43哈希查找 (11)2.44主函数 (11)3系统测试 (12)3.1上机调试 (12)3.2调试结果与分析 (13)4总结 (17)5附录 (18)1系统需求分析在信息化时代的今天,计算机技术已经是发展到一个很可观的地步了,特别是面向窗口的操作系统的出现,使得程序设计更加的容易了。

在过去计算机内存容量小,CPU计算速度慢,关于程序设计中的数据结构也因此提出来很多的关于解决这方面的问题。

哈希表就是其中之一,哈希表是一个由关键字与值组成的特殊的一种数据结构。

它的出现主要是为了解决在结构中查找记录时需要进行一系列和关键字的比较,这一类查找方法是建立在“比较”的基础上的,在顺序等的查找中,查找的效率是依赖于查找过程中所比较的次数。

理想的情况是希望不经过任何的比较一次存取便能得到所查记录,那就必须在记录的存储位置和它的关键字之间建立一个确定的对应关系,使得每个关键字和结构中一个唯一的存储位置相对应。

因而在查找时只要根据这个对应关系找到给定的值的像。

若结构中存在关键字和该值相等的记录,则所要查找的数就必定就是这个所查找到的记录。

哈希函数是建立哈希表的一个重要的成员,它的构造方法分为以下几种:直接定址法、数字分析法、平方取中法、折叠法、除留余数法、随机数法。

本程序中主要用的是除余取留法,除留取余法主要是取关键字被某个不大于哈希表表长m的数p出后所得余数为哈希地址即:H(key)=key MOD p, p<=m,这是一种最简单,也是一种最常用的构造函数的方法,它不仅可以对关键字直接取模,也可在折叠、平方中等运算之后取模。

在哈希表的建立中,很容易出现同义词,这些同义词的出现也导致了建立哈希表时冲突的出现,如果不解决这些冲突那么建立好的哈希表与预料的哈希表不同。

关于处理冲突的方法主要有:开放定址法、再哈希法、链地址法。

本程序中主要用的就是链地址法莱解决冲突的。

1.1用户需求分析设计一个程序能够使用哈希表实现电话号码查询系统。

该系统能够从键盘输入各记录,分别以电话号码和用户名为关键字建立哈希表,能够从输入记录中查找并显示给定用户的记录,最后并且能够进行清除记录和退出功能。

1.2功能需求分析(1)设计一个结点使该结点包括电话号码、用户名、地址。

(2)利用用户名和电话号码为关键字建立哈希表,哈希函数用除留余数法构照。

(3)利用链表法处理冲突问题。

(4)查找并显示给定用户名,地址,电话号码的记录。

(5)显示哈希表中的给定用户的记录。

(6)当完成操作后,可以退出系统。

1.3数据需求分析由问题分析知,本设计主要要求分别以电话号码和用户名为关键字建立哈希表,并实现查找功能。

所以本设计的核心问题是如何解决散列的问题,亦即设计一个良好的哈希表。

由于结点的个数无法确认,并且如果采用线性探测法散列算法,删除结点会引起“信息丢失”的问题。

所以采用链地址法散列算法。

采用链地址法,当出现同义词冲突时,使用链表结构把同义词链接在一起,即同义词的存储地址不是散列表中其他的空地址。

首先,解决的是定义链表结点,在链地址法中,每个结点对应一个链表结点,它由三个域组成,而由于该程序需要分别用电话号码和用户名为关键字建立哈希表,所以该链表结点它是由四个域组成.name[8] 、num[11]和address[20]都是char浮点型,输入输出都只能是浮点型的。

采用链地址法,其中的所有同义词构成一个单链表,再由一个表头结点指向这个单链表的第一个结点。

这些表头结点组成一个一维数组,即哈希表。

数组元素的下标对应由散列函数求出的散列地址。

1.4 小结通过以上需求分析,知道了设计一个哈希表的目的和能够“实现什么功能”,为接下来的操作明确方向,罗列了需要运用到的知识,自己应该在接下来的程序设计和实现应该怎么做。

2系统设计2.1设计内容及要求本设计主要要求分别以电话号码和用户名为关键字建立哈希表,并实现查找功能。

本程序的要求是设计散列函数,亦即设计一个良好的哈希表。

本程序需要设计两个散列函数才能解决问题,程序需要分别为以电话号码和用户名为关键字建立哈希表。

所以要分别以用户名、号码为关键字建立两个散列函数,要添加用户信息,即要有实现添加结点的功能的函数,所以要设计一个必须包括一个输入结点信息、添加结点的函数;要实现查找函数,则必须包括一个查找结点的函数;另外还有一个必不可少的就是运行之后要有一个主菜单,即要设计一个主函数(main())。

2.2总体设计思路本设计涉及到的数据结构为:哈希表。

要求输入电话号码、用户名、地址三个信息,并要求分别以电话号码和用户名为关键字进行查找,所以本问题要用到两个哈希函数,进行哈希查找。

在链地址法中,每个结点对应一个链表结点,它由三个域组成,而由于该程序需要分别用电话号码和用户名为关键字建立哈希表,所以该链表结点它是由四个域组成,链地址法结点结构如图:其中name[8]和num[11]是分别为以电话号码和用户名为关键字域,存放关键字(key);address[20](data)为结点的数据域,用来存储用户的地址。

Next指针是用来指向下一个结点的地址。

2.3程序详细设计流程图2.31以姓名为关键字的Hash()函数流程图1-1 姓名为关键字的Hash()函数流程图2.32添加结点信息流程图:1-2添加结点信息流程图: 2.33按姓名查找流程图:2.34按号码查找流程图2.35主程序流程图2.4详细设计编码2.41建立节点struct node //建节点{char name[8],address[20];//节点中要包含用户名,用户地址,电话号码以及指向下一个结点的指针char num[11];node * next;};typedef node* pnode; //typedef可以为一个已有的数据类型声明多个别名,这里为该类型声明了两个指针typedef node* mingzi;node **phone;node **nam;node *a;2.42对哈希函数的定义void hash(char num[11]) //以电话号码为关键字建立哈希函数{key=(int)num[2];while(num[i]!=NULL){key+=(int)num[i];i++;}key=key%20;}b)void hash2(char name[8]) //以用户名为关键字建立哈希函数{int i = 1;key2=(int)name[0];while(name[i]!=NULL){key2+=(int)name[i];i++;}key2=key2%20;}2.43哈希查找void find(char num[11]) //在以电话号码为关键字的哈希表中查找用户信息{hash(num);node *q=phone[key]->next;while(q!= NULL){if(strcmp(num,q->num)==0)break;q=q->next;}if(q)printf("%s_%s_%s\n",q->name,q->address,q->num);else printf("无此记录\n");}b)、void find2(char name[8]) // 在以用户名为关键字的哈希表中查找用户信息{hash2(name);node *q=nam[key2]->next;while(q!= NULL){if(strcmp(name,q->name)==0)break;q=q->next;}if(q)printf("%s_%s_%s\n",q->name,q->address,q->num);else printf("无此记录\n");}2.44主函数主函数本程序需要创建一个主菜单和一个主函数,主菜单便于用户的使用,主函数中,包括所有功能对应的数值,使之和主菜单相对应。

***************************主函数界面设计如下************************0添加记录1查找记录2姓名散列3号码散列4清空记录5退出系统void menu() //菜单{system("color 2d");printf("********************************************************** **********************\n");printf("\t\t\t***********欢迎使用***********\t\t\t\n");printf("\n");printf("\t\t\t\t 0.添加记录\t\t\t\t\n");printf("\t\t\t\t 1.查找记录\t\t\t\t\n");printf("\t\t\t\t 2.姓名散列\t\t\t\t\n");printf("\t\t\t\t 3.号码散列\t\t\t\t\n");printf("\t\t\t\t 4.清空记录\t\t\t\t\n");printf("\t\t\t\t 5.退出系统\t\t\t\t\n");}3系统测试3.1上机调试1首先键入0,添加结点信息,然后按1进行查找,分别进行号码和姓名查找,最后可在主菜单中,选择号码散列和姓名散列,由此查看程序运行结果。

2语法错误及修改:程序是分块写的,调试时可以使用分步调试的方式进行,以便能查找看程序是在哪出错了。

本算法使用了链表结构和链地址法解决冲突的问题,在以姓名为关键字的哈希表中要注意涉及ASCLL码的类型转换,要注意输出不能是“%d”,否则不能输出结果。

相关主题