武汉理工大学计算机哈希表课程设计Word文档格式.docx

上传人:b****6 文档编号:20713330 上传时间:2023-01-25 格式:DOCX 页数:26 大小:104.35KB
下载 相关 举报
武汉理工大学计算机哈希表课程设计Word文档格式.docx_第1页
第1页 / 共26页
武汉理工大学计算机哈希表课程设计Word文档格式.docx_第2页
第2页 / 共26页
武汉理工大学计算机哈希表课程设计Word文档格式.docx_第3页
第3页 / 共26页
武汉理工大学计算机哈希表课程设计Word文档格式.docx_第4页
第4页 / 共26页
武汉理工大学计算机哈希表课程设计Word文档格式.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

武汉理工大学计算机哈希表课程设计Word文档格式.docx

《武汉理工大学计算机哈希表课程设计Word文档格式.docx》由会员分享,可在线阅读,更多相关《武汉理工大学计算机哈希表课程设计Word文档格式.docx(26页珍藏版)》请在冰豆网上搜索。

武汉理工大学计算机哈希表课程设计Word文档格式.docx

要求完成的主要任务:

(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)

课程设计报告按学校规定格式用A4纸打印(书写),并应包含如下内容:

1、问题描述

简述题目要解决的问题是什么。

2、设计

存储结构设计、主要算法设计(用类C语言或用框图描述)、测试用例设计;

3、调试报告

调试过程中遇到的问题是如何解决的;

对设计和编码的讨论和分析。

4、经验和体会(包括对算法改进的设想)

5、附源程序清单和运行结果。

源程序要加注释。

如果题目规定了测试数据,则运行结果要包含这些测试数据和运行输出,

6、设计报告、程序不得相互抄袭和拷贝;

若有雷同,则所有雷同者成绩均为0分。

时间安排:

1、第19周完成。

2、7月1日14:

00到计算中心检查程序、交课程设计报告、源程序(CD盘)。

指导教师签名:

年月日

系主任(或责任教师)签名:

课程设计报告书

1.问题描述

1.1问题描述

针对某个集体(比如你所在的班级)中的“人名”设计一个哈希表,使得平均查找长度不超过R,完成相应的建表和查表程序。

1.2基本要求

假设人名为中国人姓名的汉语拼音形式。

1.3测试数据

取自己班级成员的名字作为测试数据,建立一个相关哈希表,并计算平均查找长度,完成查询。

2.实现分析

(1)针对某个集体中的人名设计一个哈希表,使得平均查找长度不超过R,完成相应的建立和查表程序。

(2)人名为汉语拼音形式,最长不超过19个字符(如:

庄双双zhuangshuangshuang)。

(3)假设待填入哈希表的人名有30个,平均查找长度的上限为2。

哈希表用除留余数法构造,用伪随机探测在散列法处理冲突。

(4)如果随机函数自行构造,则应首先调整好随机函数,使其分布均匀。

字符的取码方法可直接利用C语言中的toascii函数,并可对过长人名先进行折叠处理。

(5)查找成功时,显示姓名及关键字,并计算和输出查找成功的平均查找长度。

3.程序设计

3.1存储结构设计

根据哈希函数可唯一确定一个记录的地址,在理想情况下,记录就可以按照这个存储地址进行存储。

因此哈希表的存储结构可以是链表和线性表,但一般情况下选择线性表进行存储。

本次课程设计用到的存储结构如下:

typedefstruct

{char*name;

//名字的拼音

intk;

//名字拼音所对应的关键字

}NAME;

//结构体NEMA,存放名字列表

typedefstruct//哈希表

{char*name;

intsi;

//名字的查找长度

}HASH;

//结构体HASH,哈希表

3.2主要算法设计

3.2.1程序主要函数原型及功能

[1]首先定义两个结构体数组:

NAMENameList[HASH_LENGTH];

//全局变量NAME,存储原始姓名

HASHHashList[HASH_LENGTH];

//全局变量HASH,存储哈希表中的姓名

[2]主要函数原型及功能:

voidInitNameList()

功能:

主要完成初始化姓名列表,并且将字符串的各个字符所对应的ASCII码相加,所得的整数作为哈希表的关键字。

以便利用关键字和除留余数法得到每个姓名的哈希地址。

voidCreateHashList()

构建一个哈希表并进行初始化;

利用各个姓名的关键字得到哈希地址,将各个姓名按哈希地址进行存储,如果发生冲突,则利用伪随机探测再序列解决冲突,最终将姓名全部存放在哈希表中。

voidFindList()

对用户输入的姓名进行查找;

查找结果分两种情况:

(1)查找成功,则输出姓名、关键字和查找长度;

(2)查找失败,则返回相应的失败信息。

查找时关键字的求法和处理冲突的方法与函数InitNameList()、CreateHashList()中的相关算法一致。

voidShowHash()

完成度已经建立好的哈希表进行输出显示,并输出平均查找长度。

voidmain()

完成对个函数的调用和与用户的交互。

3.2.2各函数的实现

(1)初始化姓名列表:

Ø

哈希地址方法:

将字符串的各个字符所对应的ASCII码相加,所得的整数做为哈希表的关键字key。

函数voidInitNameList()的实现(以班级30人的人名作为初始值):

voidInitNameList()//姓名(结构体数组)初始化

{char*f;

intr,s0,i;

NameList[0].name="

fanxu"

;

NameList[1].name="

jiangyong"

NameList[2].name="

guyuze"

NameList[3].name="

liuzhenhai"

NameList[4].name="

chenang"

NameList[5].name="

caoyandong"

NameList[6].name="

yangchenchen"

NameList[7].name="

shenjin"

NameList[8].name="

puping"

NameList[9].name="

luhaibo"

NameList[10].name="

renchao"

NameList[11].name="

wangshichuang"

NameList[12].name="

guoqihui"

NameList[13].name="

chengkang"

NameList[14].name="

wangyuesong"

NameList[15].name="

liangfangping"

NameList[16].name="

wangxufeng"

NameList[17].name="

hejie"

NameList[18].name="

yangyiming"

NameList[19].name="

wushengping"

NameList[20].name="

yangchaoqin"

NameList[21].name="

wulinfeng"

NameList[22].name="

xiehongwei"

NameList[23].name="

liushuo"

NameList[24].name="

yijiabin"

NameList[25].name="

xuhaiyang"

NameList[26].name="

yangwenjuan"

NameList[27].name="

chenjunyan"

NameList[28].name="

wangjiaxin"

NameList[29].name="

chenwan"

for(i=0;

i<

NAME_NO;

i++)

{s0=0;

f=NameList[i].name;

for(r=0;

*(f+r)!

='

\0'

r++)/*哈希地址方法:

将字符串的各个字符所对应的ASCII码相加,所得的整数作为哈希表的关键字*/

s0=*(f+r)+s0;

NameList[i].k=s0;

}

}

(2)建立哈希表

用除留余数法构建哈希函数

用伪随机探测再散列法处理冲突

构建哈希函数voidCreateHashList()的实现:

voidCreateHashList()

{inti;

i<

HASH_LENGTH;

i++)

{HashList[i].py="

"

HashList[i].k=0;

HashList[i].si=0;

}

{intsum=0;

intadr=(NameList[i].k)%M;

//哈希函数

intd=adr;

if(HashList[adr].si==0)//如果不冲突

{HashList[adr].k=NameList[i].k;

HashList[adr].py=NameList[i].py;

HashList[adr].si=1;

else//冲突

{do

{d=(d+NameList[i].k%10+1)%M;

//伪随机探测再散列法处理冲突

sum=sum+1;

//查找次数加1

}while(HashList[d].k!

=0);

HashList[d].k=NameList[i].k;

HashList[d].py=NameList[i].py;

HashList[d].si=sum+1;

(3)查找哈希表

若查找成功,则输出姓名、关键字和查找长度;

查找失败,则返回相应的失败信息。

查找函数voidFindList()的实现:

voidFindList()//查找

{charname[20]={0};

ints0=0,r,sum=1,adr,d;

printf("

请输入姓名的拼音:

);

scanf("

%s"

name);

r<

20;

r++)//求出姓名的拼音所对应的整数(关键字)

s0+=name[r];

adr=s0%M;

//使用哈希函数

d=adr;

if(HashList[adr].k==s0)//分3种情况进行判断

\n姓名:

%s关键字:

%d查找长度为:

1"

HashList[d].py,s0);

elseif(HashList[adr].k==0)

无此记录!

else

{intg=0;

do

{d=(d+s0%10+1)%M;

if(HashList[d].k==0)

{printf("

"

g=1;

}

if(HashList[d].k==s0)

%d"

HashList[d].py,s0,sum);

}while(g==0);

(4)显示哈希表

显示哈希表的的格式:

\n地址\t关键字\t\t搜索长度\tH(key)\t姓名\n

显示哈希表的函数voidDisplay()的:

voidDisplay()//显示

floataverage=0;

\n地址\t关键字\t\t搜索长度\tH(key)\t姓名\n"

//显示的格式

50;

i++)

{printf("

%d"

i);

\t%d"

HashList[i].k);

\t\t%d"

HashList[i].si);

HashList[i].k%M);

\t%s"

HashList[i].py);

\n"

average+=HashList[i].si;

average/=NAME_NO;

\n平均查找长度:

ASL(%d)=%f\n"

NAME_NO,average);

(5)主函数设计

{charch1;

InitNameList();

CreateHashList();

D.显示哈希表\nF.查找\nQ.退出\n请选择:

cin>

>

&

ch1;

switch(ch1)

{

case'

D'

:

Display();

cout<

<

endl;

break;

F'

FindList();

cout<

Q'

exit(0);

}

cout<

comeon!

(y/n):

}while(ch1!

n'

3.2.3函数模块

模块调用关系

主函数模块

输出模块

查找模块

哈希表模块

姓名初始化模块

3.2.4程序流程图

本次程序流程图如下

4.调试报告

4.1调试中的问题

经过对哈希表的研究后,即进行程序的设计和编码;

将原程序编好后,经过编译,有如下几个问题:

在声明了结构体NAME后,最开始结构体内的charname[20]用来存放姓名拼音,最长为20位;

经分析,name表示所存姓名拼音的首地址,无需再申明具体的数组长度来存放姓名拼音,这样增加了系统的开销,最后改成char*name,对存放姓名拼音时直接对name赋值,系统直接按照字符数组来存放姓名拼音,而存放长度没有固定。

建立哈希表的函数:

voidCreateHashList()中,如果遇到冲突后,在do{}while();

语句中,利用伪随机探测再散列法处理冲突,没执行一次就要将记录查找长度的sum增加一次,在这个循环执行完后,即找到一个不冲突的地址来存放姓名拼音,经过自习分析,此时的查找长度需要加1,即将原来的语句HashList[d].si=sum;

改成HashList[d].si=sum+1;

此时的HashList[d].si才是正确的查找长度。

main函数中的do{}while()语句中,最开始while()语句是:

while(a!

N'

||a!

)经过分析,在用户需要退出时,不论输入a=N还是a=n,都将继续循环;

经过自习思考,最终将while()语句改成:

while(a=='

Y'

||a=='

y'

),这样就实现了用户的选择。

4.2对设计和编码的讨论和分析

算法采用结构体和数组来存储数据,利用除留余数法得到哈希地址,利用为随机序列法来处理冲突,姓名拼音的关键字为字符串的各个字符所对应的ASCII码相加,所得的整数。

求哈希地址时模为51,哈希表的总长度为50,而实际名字只有30个,因此有20个地址空间被空闲着,这浪费了一定的内存。

算法的时间复杂度为:

O(n)。

平均查找长度为:

1.566667

装填因子为:

30/50=0.6

5.程序运行结果

经过对程序错误的修改后,程序执行,经过分析,程序运行结果正确,满足题目要求!

运行结果主要截图如下:

程序开始后,初始界面为:

选择S后结果为:

结果显示,平均查找长度为1.566667,符合题设要求!

选择Y继续后选择F查找

查找成功结果为:

查找失败结果为:

6.经验和体会

6.1感受和体会

《数据结构》这门课程是计算机专业一门基础性学科,重要性可见一斑,学好这门课程对以后人生的发展具有深远的影响。

而数据结构的课程设计便是对学习效果的检验。

数据结构课程设计不仅可以锻炼我们独立思考问题、解决问题的能力,而且可以培养我们的整体性思维的能力;

通过课程设计,使我了解了很多数据结构的经典问题和经典算法,加深了对数据结构的再认识,巩固了数据结构的基础性知识,比如:

存储结构、数据查找、哈希表的设计和查找、算法分析等。

哈希表是根据关键码值而直接进行访问的数据结构,它把关键码值通过哈希函数映射到表中一个地址来存储记录,以加快查找的速度。

哈希函数的构造方法有:

直接寻址法、数字分析法、平方取中法、折叠法、随机数法、除留余数法等;

对于地址冲突要进行解决,主要解决冲突的的方法有:

开放寻址法(线性探测再散列、二次探测再散列、伪随机探测再散列)、再散列法、链地址法、建立一个公共溢出区等。

查找过程中,关键码的比较次数,取决于产生冲突的多少,产生的冲突少,查找效率就高,产生的冲突多,查找效率就低。

因此,影响产生冲突多少的因素,也就是影响查找效率的因素。

影响产生冲突多少有以下三个因素:

散列函数是否均匀、处理冲突的方法、散列表的装填因子。

通过查找相关资料还了解了著名的hash算法:

MD4、MD5、SHA-1及其他。

哈希表的主要用途为:

文件校验、数字签名、鉴权协议等。

这也是对于以后继续研究数据结构所必须了解的知识。

这次课程设计,我明白了对于编写程序,解题的思路尤为重要。

在编写程序之前,如果没有比较清晰的思路,根本不可能编出好的程序。

就算马马虎虎的编出来,程序的逻辑性、健壮性、完善性、合理性也不会很强。

在编程之前,我们应反复研究题目要求,对题目涉及的情况进行比较充分的分析,以便编写出更加符合题意的程序;

其次要充分考虑各种临界情况,对一些错误的输入进行处理。

因此在我们编程序之前一定要做好充分的准备,首先要理清自己的思路,然后再将思路分划成几个模块,逐块的写好算法,最后再将所有的模块有机的联系起来,组成一个完整的程序。

在成功通过编译的情况下,对程序运行的结果进行系统的分析,检验其正确性,如果有错误,应立即去分析源程序的逻辑错误,直到得到正确的结果。

在这次课程设计的过程中,我也遇到了很多难题。

在种种的困难中,我明白了在编写程序时要有耐心。

如果你没有耐心,即使再好的算法思路也不会得到很好的表达,特别是在调试的过程中,对于各种各样的错误,要特别的有耐心去自习分析原因,特别是一些基本的语法错误,不能一看到错误很多就乱了阵脚,更不能轻易的放弃,半途而废。

比如在调试中没有定义某些变量的错误、基本的输入输出错误、数据选取不合理的错误、变量名前后不一的错误、函数返回值的错误等等。

其实只要有耐心,你就会发现,在你修改了一个错误之后,其它有的错误也会跟着消失,所以在编译的时候一定要有耐心。

数据结构是一门比较难的课程,需要花很多的时间去不断地练习和实践。

要想把这门课程学好学精并非一件容易的事,特别是一些经典算法,是几十年前人智慧的结晶,对于初学者的理解和应用有一定的难度;

但是事在人为,只要肯下功夫,便一定可以学好。

总的来说,这次程序设计让我获益匪浅,相信在以后的学习生活中我也能从中获得启发。

6.2对算法改进的想法

本次哈希表的设计采用的存储结构为顺序存储,这样的存储结构简单易操作,但是必须实现给定存储大小,这样不利于动态操作,在题目允许的情况下,可以采用链式存储结构,从而实现动态存储;

对关键字的选取还可以按照各个姓名的字母表的顺序等方式,哈希地址的除留余数法的模还可以是其他的接近表长的素数,解决冲突的伪随机序列取余的模长也可以是其他的接近表长的素数;

本次哈希表的总长度为50,而实际只用到了30个,还余下20个空闲地址被白白浪费了,可以在满足题目要求的情况下适当的选取小一点的总表长。

7.哈希表和源程序

7.1哈希表

经过分析,最后得到的哈希表如下:

搜索

长度

地址

存储内容

关键字

H(key)

1

(null)

wangjiaxin

1072

2

liuzhenhai

1073

4

3

chenjunyan

1075

5

xuhaiyang

974

6

wangshichuang

1383

7

hejie

517

8

guoqihui

875

9

10

chenang

724

11

wangxufeng

1082

12

wulinfeng

975

13

yangyiming

1084

14

15

16

chengkang

934

17

18

guyuze

681

19

20

liushuo

777

21

22

renchao

736

23

24

yangwenjuan

1191

25

26

luhaibo

740

27

chenwan

28

xiehongwei

1079

29

30

31

yijiabin

847

32

33

34

wangyuesong

1207

35

yangchenchen

1259

36

fanxu

546

37

shenjin

751

38

39

caoyandong

1059

40

41

42

43

44

45

liangfangping

1365

46

wushengping

1199

47

puping

659

48

jiangyong

966

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工作范文 > 制度规范

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1