数据结构实验报告七查找.docx
- 文档编号:25671976
- 上传时间:2023-06-11
- 格式:DOCX
- 页数:22
- 大小:78.44KB
数据结构实验报告七查找.docx
《数据结构实验报告七查找.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告七查找.docx(22页珍藏版)》请在冰豆网上搜索。
数据结构实验报告七查找
(本实验项目方案受“教育部人才培养模式创新实验区(X3108005)”项目资助)
实验难度:
A□B□C□
序号
学号
姓名
成绩
1
2
3
指导教师
(签名)
学 期:
2010秋季学期
任课教师:
实验题目:
查找算法设计与实现
姓名:
王辉
学号:
20091120154
电子邮件:
完成提交时间:
2010年12月27日
云南大学软件学院2010学年秋季学期
《数据结构实验》成绩考核表
学号:
姓名:
本人承担角色:
评分项目
评分指标
分值
得分
实验构思(10%)
1.实验目的明确
5
2.实验内容理解透彻、对实验所涉及到的知识点分析到位
5
实验设计(15%)
1.有对基本数据结构的抽象数据类型定义
5
2.实验方案设计完整,数据结构、算法选择合理
5
3.算法结构和程序功能模块之间逻辑清晰、有相应的流程图
5
实验实现(25%)
1.代码编写规范、风格统一、注释清楚易读
5
2.程序运行正常,测试结果正确
15
3.界面友好、易于操作、有较强的容错性
5
实验报告撰写(10%)
1.内容详实无缺漏,文字流畅、图表清楚
5
2.实验结果分析客观、详细,实验体会真实可信,对原实验方案的改进和对实验内容的发散性思考
5
个人工作量(30%)
1.个人完成工作量
15
2.个人技术水平
10
3.团队合作精神
5
实验运作(10%)
1.有一定用户群
5
2.应用前景分析
5
综合得分:
(满分100分)
指导教师:
年月日
(注:
此表在难度为C时使用,每个成员一份。
)
(下面的内容由学生填写,格式统一为,字体:
楷体,行距:
固定行距18,字号:
小四,个人报告按下面每一项的百分比打分。
难度A满分70分,难度B满分90分)
一、【实验构思(Conceive)】(10%)
1哈希表查找。
根据全年级学生的姓名,构造一个哈希表,选择适当的哈希函数和解决冲突的方法,设计并实现插入、删除和查找算法。
熟悉各种查找算法的思想。
2、掌握查找的实现过程。
3、学会在不同情况下运用不同结构和算法求解问题。
4把每个学生的信息放在结构体中:
typedefstruct//记录
{
NAname;
NAtel;
NAadd;
}Record;
5voidgetin(Record*a)函数依次输入学生信息
6人名折叠处理,先将用户名进行折叠处理折叠处理后的数,用除留余数法构造哈希函数,并返回模值。
并采用二次探测再散列法解决冲突。
7姓名以汉语拼音形式,待填入哈希表的人名约30个,自行设计哈希函数,用线性探测再散列法或链地址法处理冲突;在查找的过程中给出比较的次数。
完成按姓名查询的操作。
将初始班级的通讯录信息存入文件。
二、【实验设计(Design)】(20%)
(本部分应包括:
抽象数据类型的功能规格说明、主程序模块、各子程序模块的伪码说明,主程序模块与各子程序模块间的调用关系)
1抽象数据类型的功能规格说明和结构体:
#include
#include
#include
#include
#defineMAXSIZE20//电话薄记录数量
#defineMAX_SIZE20//人名的最大长度
#defineHASHSIZE53//定义表长
#defineSUCCESS1
#defineUNSUCCESS-1
#defineLENsizeof(HashTable)
typedefintStatus;
typedefcharNA[MAX_SIZE];
typedefstruct//记录
{
NAname;
NAtel;
NAadd;
}Record;
typedefstruct//哈希表
{
Record*elem[HASHSIZE];//数据元素存储基址
intcount;//当前数据元素个数
intsize;//当前容量
}HashTable;
2主函数与各子函数的调用关系:
(通过switch(num)函数按不同功能要求分别调用相关函数)
intmain(intargc,char*argv[]){
system("color61");
intc,flag=1;
HashTable*H;
H=(HashTable*)malloc(LEN);
for(inti=0;i H->elem[i]=NULL; H->size=HASHSIZE; H->count=0; Recorda[MAXSIZE]; while (1) { printf("\n★☆★☆★☆★☆★☆wanghui★☆★☆★☆★☆★☆★☆"); printf("\n★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★"); printf("\n★☆★☆我的未来不是梦★☆★☆"); printf("\n★☆★☆无聊中郁闷死★☆★☆"); printf("\n★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★"); printf("\n┏━━━━━━━━━━━━━┓"); printf("\n★┃欢迎欢迎欢迎欢迎欢迎欢迎┃★"); printf("\n〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓"); printf("\n★★★★★★★哈希表的设计与实现★★★★★★"); printf("\n【】.添加用户信息"); printf("\n【】.读取所有用户信息"); printf("\n【】.以姓名建立哈希表(再哈希法解决冲突)"); printf("\n【】.以电话号码建立哈希表(再哈希法解决冲突)"); printf("\n【】.查找并显示给定用户名的记录"); printf("\n【】.查找并显示给定电话号码的记录"); printf("\n【】.清屏"); printf("\n【】.保存"); printf("\n【】.退出程序"); printf("\n温馨提示: "); printf("\nⅠ.进行操作前请先输出"); printf("\nⅡ.进行操作前请先输出"); printf("\n★★★★★★★〓〓〓〓〓〓〓〓〓★★★★★★"); printf("\n"); printf("请输入一个任务选项>>>"); printf("\n"); intnum; scanf("%d",&num); switch(num){ case1: getin(a); break; case2: ShowInformation(a); break; case3: CreateHash1(H,a);/*以姓名建立哈希表*/ break; case4: CreateHash2(H,a);/*以电话号码建立哈希表*/ break; case5: c=0; SearchHash1(H,c); break; case6: c=0; SearchHash2(H,c); break; case7: Cls(a); break; case8: Save(); break; case9: return0; break; default: printf("你输错了,请重新输入! "); printf("\n"); } } system("pause"); return0; } 三、【实现描述(Implement)】(30%) (本部分应包括: 抽象数据类型具体实现的函数原型说明、关键操作实现的伪码算法、函数设计、函数间的调用关系,关键的程序流程图等,给出关键算法的时间复杂度分析。 ) 1主函数打印和主子函数调用: intmain(intargc,char*argv[]){ system("color61"); intc,flag=1; HashTable*H; H=(HashTable*)malloc(LEN); for(inti=0;i H->elem[i]=NULL; H->size=HASHSIZE; H->count=0; Recorda[MAXSIZE]; while (1) { printf("\n★☆★☆★☆★☆★☆申平★☆★☆★☆★☆★☆★☆"); printf("\n★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★"); printf("\n★☆★☆我的未来不是梦★☆★☆"); printf("\n★☆★☆无聊中郁闷死★☆★☆"); printf("\n★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★"); printf("\n┏━━━━━━━━━━━━━┓"); printf("\n★┃欢迎欢迎欢迎欢迎欢迎欢迎┃★"); printf("\n〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓"); printf("\n★★★★★★★哈希表的设计与实现★★★★★★"); printf("\n【】.添加用户信息"); printf("\n【】.读取所有用户信息"); printf("\n【】.以姓名建立哈希表(再哈希法解决冲突)"); printf("\n【】.以电话号码建立哈希表(再哈希法解决冲突)"); printf("\n【】.查找并显示给定用户名的记录"); printf("\n【】.查找并显示给定电话号码的记录"); printf("\n【】.清屏"); printf("\n【】.保存"); printf("\n【】.退出程序"); printf("\n温馨提示: "); printf("\nⅠ.进行操作前请先输出"); printf("\nⅡ.进行操作前请先输出"); printf("\n★★★★★★★〓〓〓〓〓〓〓〓〓★★★★★★"); printf("\n"); printf("请输入一个任务选项>>>"); printf("\n"); intnum; scanf("%d",&num); switch(num){ case1: getin(a); break; case2: ShowInformation(a); break; case3: CreateHash1(H,a);/*以姓名建立哈希表*/ break; case4: CreateHash2(H,a);/*以电话号码建立哈希表*/ break; case5: c=0; SearchHash1(H,c); break; case6: c=0; SearchHash2(H,c); break; case7: Cls(a); break; case8: Save(); break; case9: return0; break; default: printf("你输错了,请重新输入! "); printf("\n"); } } system("pause"); return0; } 2键盘输入各人的信息: voidgetin(Record*a)//键盘输入各人的信息 { system("cls"); printf("输入要添加的个数: \n"); scanf("%d",&NUM_BER); inti; for(i=0;i printf("请输入第%d个记录的用户名: \n",i+1); scanf("%s",a[i].name); printf("请输入%d个记录的电话号码: \n",i+1); scanf("%s",a[i].tel); printf("请输入第%d个记录的地址: \n",i+1); scanf("%s",a[i].add);//gets(str2);? ? ? ? ? ? } } 3显示输入的用户信息和人名的折叠处理: voidShowInformation(Record*a)//显示输入的用户信息 { system("cls"); inti; for(i=0;i printf("\n第%d个用户信息: \n姓名: %s\n电话号码: %s\n联系地址: %s\n",i+1,a[i].name,a[i].tel,a[i].add); } voidCls(Record*a){ printf("*"); system("cls"); } longfold(NAs)//人名的折叠处理 { char*p; longsum=0; NAss; strcpy(ss,s);//复制字符串,不改变原字符串的大小写 strupr(ss);//将字符串ss转换为大写形式 p=ss; while(*p! ='\0') sum+=*p++; printf("\nsum====================%d",sum); returnsum; } 5哈希函数,先将用户名进行折叠处理,折叠处理后的数,用除留余数法构造哈希函数并返回模值;把字符串转换成整型数,用除留余数法构造哈希函数并返回模值: intHash1(NAstr)//哈希函数 { longn; intm; n=fold(str);//先将用户名进行折叠处理 m=n%HASHSIZE;//折叠处理后的数,用除留余数法构造哈希函数 returnm;//并返回模值 } intHash2(NAstr)//哈希函数 { longn; intm; n=atoi(str);//把字符串转换成整型数. m=n%HASHSIZE;//用除留余数法构造哈希函数 returnm;//并返回模值 } 6冲突处理函数,采用二次探测再散列法解决冲突: Statuscollision(intp,int&c)//冲突处理函数,采用二次探测再散列法解决冲突 { inti,q; i=c/2+1; while(i if(c%2==0){ c++; q=(p+i*i)%HASHSIZE; if(q>=0)returnq; elsei=c/2+1; } else{ q=(p-i*i)%HASHSIZE; c++; if(q>=0)returnq; elsei=c/2+1; } } returnUNSUCCESS; } voidbenGetTime(); voidCreateHash1(HashTable*H,Record*a)//建表,以人的姓名为关键字,建立相应的散列表 { system("cls");//若哈希地址冲突,进行冲突处理 benGetTime(); inti,p=-1,c,pp; for(i=0;i c=0; p=Hash1(a[i].name); pp=p; while(H->elem[pp]! =NULL){ pp=collision(p,c); if(pp<0){ printf("第%d记录无法解决冲突",i+1);//需要显示冲突次数时输出 continue; }//无法解决冲突,跳入下一循环 } H->elem[pp]=&(a[i]);//求得哈希地址,将信息存入 H->count++; printf("第%d个记录冲突次数为%d。 \n",i+1,c);//需要显示冲突次数时输出 } printf("\n建表完成! \n此哈希表容量为%d,当前表内存储的记录个数为%d.\n",HASHSIZE,H->count); benGetTime(); } 7在通讯录里查找姓名关键字,若查找成功,显示信息: voidSearchHash1(HashTable*H,int&c)//在通讯录里查找姓名关键字,若查找成功,显示信息 { system("cls");//c用来记录冲突次数,查找成功时显示冲突次数 benGetTime(); NAstr; printf("\n请输入要查找记录的姓名: \n"); scanf("%s",str); intp,pp; p=Hash1(str); pp=p; while((H->elem[pp]! =NULL)&&(eq(str,H->elem[pp]->name)==-1)) pp=collision(p,c); if(H->elem[pp]! =NULL&&eq(str,H->elem[pp]->name)==1){ printf("\n查找成功! \n查找过程冲突次数为%d.以下是您需要要查找的信息: \n\n",c); printf("姓名: %s\n电话号码: %s\n联系地址: %s\n",H->elem[pp]->name,H->elem[pp]->tel,H->elem[pp]->add); } elseprintf("\n此人不存在,查找不成功! \n"); benGetTime(); } 8建表,以电话号码为关键字,建立相应的散列表,若哈希地址冲突,进行冲突处理: voidCreateHash2(HashTable*H,Record*a)//建表,以电话号码为关键字,建立相应的散列表 { //若哈希地址冲突,进行冲突处理 benGetTime(); inti,p=-1,c,pp; for(i=0;i c=0; p=Hash2(a[i].tel); pp=p; while(H->elem[pp]! =NULL){ pp=collision(p,c); if(pp<0){ printf("第%d记录无法解决冲突",i+1);//需要显示冲突次数时输出 continue; }//无法解决冲突,跳入下一循环 } H->elem[pp]=&(a[i]);//求得哈希地址,将信息存入 H->count++; printf("第%d个记录冲突次数为%d。 \n",i+1,c);//需要显示冲突次数时输出 } printf("\n建表完成! \n此哈希表容量为%d,当前表内存储的记录个数为%d.\n",HASHSIZE,H->count); benGetTime(); } 9在通讯录里查找电话号码关键字,若查找成功,显示信: voidSearchHash2(HashTable*H,int&c)//在通讯录里查找电话号码关键字,若查找成功,显示信息 { system("cls");//c用来记录冲突次数,查找成功时显示冲突次数 benGetTime(); NAtele; printf("\n请输入要查找记录的电话号码: \n"); scanf("%s",tele); intp,pp; p=Hash2(tele); pp=p; while((H->elem[pp]! =NULL)&&(eq(tele,H->elem[pp]->tel)==-1)) pp=collision(p,c); if(H->elem[pp]! =NULL&&eq(tele,H->elem[pp]->tel)==1){ printf("\n查找成功! \n查找过程冲突次数为%d.以下是您需要要查找的信息: \n\n",c); printf("姓名: %s\n电话号码: %s\n联系地址: %s\n",H->elem[pp]->name,H->elem[pp]->tel,H->elem[pp]->add); } elseprintf("\n此人不存在,查找不成功! \n"); benGetTime(); } voidSave(){ FILE*fp; if((fp=fopen("c: \test.txt","w"))==NULL){ printf("\nERRORopeningcustometfile"); } fclose(fp); } 四、【测试结果(Testing)】(10%) (本部分应包括: 对实验的测试结果,应具体列出每次测试所输入的数据以及输出的数据,并对测试结果进行分析总结) 五、【实验总结】(10%) (本部分应包括: 自己在实验中完成的任务,注意组内的任意一位同学都必须独立完成至少一项接口的实现;对所完成实验的经验总结、心得) 1通常有两类方法处理冲突: 开放定址(OpenAddressing)法和拉链(Chaining)法。 前者是将所有结点均存放在散列表T[0..m-1]中;后者通常是将互为同义词的结点链成一个单链表,而将此链表的头指针放在散列表T[0..m-1]中。 2用开放定址法解决冲突的做法是: 当冲突发生时,使用某种探查(亦称探测)技术在散列表中形成一个探查(测)序列。 沿此序列逐个单元地查找,直到找到给定的关键字,或者碰到一个开放的地址(即该地址单元为空)为止(若要插入,在探查到开放的地址,则可将待插入的新结点存人该地址单元)。 查找时探查到开放的地址则表明表中无待查的关键字,即查找失败。 注意: ①用开放定址法建立散列表时,建表前须将表中所有单元(更严格地说,是指单元中存储的关键字)置空。 ②空单元的表示与具体的应用相关。 3拉链法解决冲突的方法 拉链法解决冲突的做法是: 将所有关键字为同义词的结点链接在同一个单链表中。 若选定的散列表长度为m,则可将散列表定义为一个由m个头指针组成的指针数组T[0..m-1]。 凡是散列地址为i的结点,均插入到以T[i]为头指针的单链表中。 T中各分量的初值均应为空指针。 在拉链法中,装填因子α可以大于1,但一般均取α≤1. 4拉链法的优点 与开放定址法相比,拉链法有如下几个
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 实验 报告 查找