《数据结构课程设计实验报告.doc》由会员分享,可在线阅读,更多相关《数据结构课程设计实验报告.doc(53页珍藏版)》请在三一办公上搜索。
1、数据结构课程设计任务书 学期:12-13-1 班级:软件111一、设计目的数据结构是一门实践性较强的软件基础课程,为了学好这门课程,必须在掌握理论知识的同时,加强上机实践。本课程设计的目的就是要达到理论与实际应用相结合,使同学们能够根据数据对象的特性,学会数据组织的方法,能把现实世界中的实际问题在计算机内部表示出来,并培养基本的、良好的程序设计技能。二、设计要求1、通过这次设计,要求在数据结构的逻辑特性和物理表示、数据结构的选择应用、算法的设计及其实现等方面加深对课程基本内容的理解。同时,在程序设计方法以及上机操作等基本技能和科学作风方面受到比较系统和严格的训练。2、学生必须仔细研读数据结构课
2、程设计(实习)要求,以学生自学为主、指导教师指导为辅,认真、独立地完成课程设计的任务,有问题及时主动与指导教师沟通。3、本次课程设计按照教学要求需要在三周时间内独立完成,学生要发挥自主学习的能力,充分利用时间,安排好课设的时间计划,并在课设过程中不断检测自己的计划完成情况,及时地向指导教师汇报。4、编程语言任选。三、设计选题说明:课程设计题目主要分为两大类:,主要是验证性题,少数是简单的综合性题,侧重考查学生对数据结构课程中重要数据结构和算法的理解与掌握程度,相对较简单;本类题目选题要求:要求个人所选题目必须独立完成;原则上不得参考别人的程序,若个人能力有限必须参考,参考成分不得超过30%,其
3、中参考部分自己必须能消化吸收,否则视为无效;为培养学生分析问题、解决问题的实际动手能力和团队协作能力,鼓励有能力的学生尽可能选作难度较高的题目,故仅选作一星题目的学生,无论完成多少题目,原则上最高分不超出70分;仅选作一星和二星题目的学生,无论完成多少题目,原则上最高分不超出85分注意:上述题目,可以相互讨论,但严禁搭便车,杜绝拷贝或分享别人的劳动果实,坚决杜绝让别人代做。一经发现、核实,无论是拷贝者或是被拷贝者的成绩均视为不及格,情节严重者将交由学工办通报批评并受到相应的纪律处分。选题说明:一个*的题代表满分10分,出色完成者方可得满分,下同;两个*的代表满分15分,三个*的题代表满分30分
4、,四个*的题代表60分。验收时将根据实际选做题目的分值和数量以及实现程序的完善性可以适当加减分;同学们在选题时,要结合个人实际情况,力争多做,必须保证所选题目总分应该在100分以上,保障及格。第一题(一)设计内容简介散列表的设计与实现(*)任务:设计散列表实现电话号码查找系统。要求: (1) 设每个记录有下列数据项:用户名、电话号码、地址; (2) 从键盘输入各记录,以用户名(汉语拼音形式)为关键字建立散列表; (3) 采用一定的方法解决冲突; (4) 查找并显示给定电话号码的记录; 选作内容: (1) 系统功能的完善; (2) 设计不同的散列函数,比较冲突率; (3) 在散列函数确定的前提下
5、,尝试各种不同类型处理冲突的方法,考察平均查找长度的变化。(二)算法设计说明此算法要用散列表实现,里面必须涉及到哈希表的建立,整个程序要实现的功能有:添加用户信息;读取所有用户信息; 以姓名建立哈希表;以电话号码建立哈希表; 查找并显示给定用户名的记录;查找并显示给定电话号码的记录;清屏以及保存功能。定义电话本记录数量(MAXSIZE)、表长(HASHSIZE)、姓名长度(MAX_SIZE)以及结构体typedef struct的内容,构造两个哈希函数hash1和hash2。解决冲突的办法,姓名用折叠法处理,电话号码取其整型长度,hash1是用姓名建立的哈希函数,hash2是用电话号码建立的哈
6、希函数,两个哈希函数都是用除留余数法实现。处理冲突的函数,采用二次探测法。(三)测试结果1.程序的主界面,包含程序的各个功能:2.添加用户信息的测试结果:3.用哈希数查找第一个用户的信息:(四)分析与探讨这道题主要解决在查找用户时解决冲突。利用哈希表。程序的功能像添加用户信息,读取所有用户信息,清屏以及保存功能 ,都很容易实现,而像以姓名建立哈希表;以电话号码建立哈希表; 查找并显示给定用户名的记录;查找并显示给定电话号码的记录这些就比较难点。要想实现这些,必须了解关于散列表的一些基本定义和原理。以姓名建立哈希表的主要函数:void CreateHash1(HashTable* H,Recor
7、d* a) for(i=0;ielempp!=NULL)pp=collision(p,c);if(pp0)cout第i+1elempp=&(ai);H-count+;cout第i+1个记录冲突次数为c.n;coutn建表完成!n此哈希表容量为HASHSIZE,当前表内存储的记录个数为count.n; benGetTime();其中的难点就是管理冲突的解决办法,方法就是用二次探测法,主要实现:void SearchHash1(HashTable* H,int &c)benGetTime();NA str;coutstr;int p,pp;p=Hash1(str);pp=p;while(H-ele
8、mpp!=NULL) & (eq(str,H-elempp-name)=-1)pp=collision(p,c);if(H-elempp!=NULL&eq(str,H-elempp-name)=1)coutn查找成功!n查找过程冲突次数为c;cout姓名:elempp-namen电话号码:elempp-teln联系地址:elempp-addn;else coutn此人存在,查找不成功!n;(五) 流程图开始进入录入系统获得关键字key用Hash1(key)计算地址nam_2(d) =关键字?输出记录用探查序列d+i*hash2(key)计算(寻找)散列地址结束nam_Ht(d) =关键字?未找
9、到记录 (六) 附录:源代码#include#include#include#include #define MAXSIZE 20 /电话薄记录数量 #define MAX_SIZE 20 /人名的最大长度#define HASHSIZE 53 /定义表长 #define SUCCESS 1#define UNSUCCESS -1#define LEN sizeof(HashTable)typedef int Status; /自定义类型语句typedef char NAMAX_SIZE;typedef struct/记录NA name;NA tel;NA add;Record;typedef
10、 struct/哈希表Record *elemHASHSIZE; /数据元素存储基址int count; /当前数据元素个数int size; /当前容量HashTable;/关键字比较功能的实现Status eq(NA x,NA y)/关键字比较,相等返回SUCCESS;否则返回UNSUCCESSif(strcmp(x,y)=0)return SUCCESS;else return UNSUCCESS;/记录个数功能的实现Status NUM_BER; /记录定义的个数/输入信息功能void getin(Record* a)/键盘输入各人的信息coutNUM_BER;for(int i=0;
11、iNUM_BER;i+)cout请输入第i+1ai.name;cout请输入第i+1ai.tel;cout请输入第i+1ai.add;/显示输入信息的实现void ShowInformation(Record* a)/显示输入的用户信息 for(int i=0;iNUM_BER;i+) coutn第i+1个用户信息:n 姓名:ai.namen 电话号码:ai.teln 联系地址:ai.addn; /清屏功能的实现void Cls(Record* a)system(cls);long fold(NA s)/人名的折叠处理char *p;long sum=0;NA ss;strcpy(ss,s);
12、/复制字符串,不改变原字符串的大小写strupr(ss);/将字符串ss转换为大写形式p=ss;while(*p!=0)sum+=*p+;coutnsum=sum; return sum;/构造哈希函数int Hash1(NA str)/哈希函数long n;int m;n=fold(str);/先将用户名进行折叠处理m=n%HASHSIZE; /折叠处理后的数,用除留余数法构造哈希函数return m; /并返回模值int Hash2(NA str)/哈希函数long n;int m;n = atoi(str);/把字符串转换成整型数.m=n%HASHSIZE; /用除留余数法构造哈希函数r
13、eturn m; /并返回模值/冲突处理函数,用于解决冲突Status collision(int p,int &c)/冲突处理函数,采用二次探测法int i,q;i=c/2+1;while(i=0) return q;else i=c/2+1;elseq=(p-i*i)%HASHSIZE;c+;if(q=0) return q;else i=c/2+1;return UNSUCCESS;void benGetTime();void CreateHash1(HashTable* H,Record* a)/建表,以人的姓名为关键字,建立相应的散列表benGetTime();int i,p=-1,
14、c,pp; for(i=0;ielempp!=NULL)pp=collision(p,c);if(pp0)cout第i+1elempp=&(ai); /求得哈希地址,将信息存入H-count+;cout第i+1个记录冲突次数为c.n;/需要显示冲突次数时输出coutn建表完成!n此哈希表容量为HASHSIZE,当前表内存储的记录个数为count.n; benGetTime();/查找功能的实现void SearchHash1(HashTable* H,int &c)/在通讯录里查找姓名关键字,若查找成功,显示信息benGetTime();NA str;coutstr;int p,pp;p=Ha
15、sh1(str);pp=p;while(H-elempp!=NULL) & (eq(str,H-elempp-name)=-1)pp=collision(p,c);if(H-elempp!=NULL&eq(str,H-elempp-name)=1)coutn查找成功!n查找过程冲突次数为c以下是您需要要查找的信息:nn;cout姓名:elempp-namen电话号码:elempp-teln联系地址:elempp-addn;else coutn此人不存在,查找不成功!n;benGetTime();void benGetTime()SYSTEMTIME sys; GetLocalTime( &sy
16、s ); coutsys.wYearsys.wMonthsys.wDaysys.wHoursys.wMinutesys.wSecondsys.wMilliseconds; void CreateHash2(HashTable* H,Record* a)/建表,以电话号码为关键字,建立相应的散列表benGetTime();int i,p=-1,c,pp; for(i=0;ielempp!=NULL) pp=collision(p,c);if(pp0)cout第i+1elempp=&(ai); /求得哈希地址,将信息存入H-count+;cout第i+1个记录冲突次数为c。n;/需要显示冲突次数时
17、输出coutn建表完成!n此哈希表容量为HASHSIZE,当前表内存储的记录个数为count.n;benGetTime();void SearchHash2(HashTable* H,int &c)/在通讯录里查找电话号码关键字,若查找成功,显示信息benGetTime();NA tele;couttele;int p,pp;p=Hash2(tele);pp=p;while(H-elempp!=NULL)&(eq(tele,H-elempp-tel)=-1)pp=collision(p,c);if(H-elempp!=NULL&eq(tele,H-elempp-tel)=1)coutn查找成功
18、!n查找过程冲突次数为c以下是您需要要查找的信息:nn;cout姓名:elempp-namen电话号码:elempp-teln联系地址:elempp-addn;else coutn此人不存在,查找不成功!n;benGetTime();/主界面功能的实现:int main(int argc, char* argv)int c,flag=1;HashTable *H;H=(HashTable*)malloc(LEN);for(int i=0;ielemi=NULL;H-size=HASHSIZE;H-count=0;Record aMAXSIZE;while (1)coutn 欢迎使用电话号码查找
19、系统 ; coutn coutn ; coutn * 哈希表的设计与实现* ;coutn # ; coutn 1. 添加用户信息 ;coutn 2. 读取所有用户信息 ;coutn 3. 以姓名建立哈希表(解决冲突) ;coutn 4. 以电话号码建立哈希表(解决冲突) ;coutn 5. 查找并显示给定用户名的所有信息 ;coutn 6. 查找并显示给定电话号码的所有信息 ;coutn 7. 清屏处理 ;coutn 8. 退出程序 ; coutn _ 温馨提示: ; coutn 进行5操作前 请先运行3 ; coutn 进行6操作前 请先运行4 (否则查找失败!) ; coutn ;cout
20、n;cout;coutnum;switch(num) case 1:getin(a); break;case 2:ShowInformation(a);break;case 3: CreateHash1(H,a); /以姓名建立哈希表 break;case 4: CreateHash2(H,a); /以电话号码建立哈希表break; case 5:c=0;SearchHash1(H,c); break; case 6:c=0;SearchHash2(H,c); break; case 7:Cls(a);break;case 8:return 0;break;default:cout你输错了,请
21、重新输入!;coutn; system(pause);return 0;第二题文章编辑功能:输入一页文字,程序可以统计出文字、数字、空格的个数。静态存储一页文章,每行最多不超过80个字符,共N行;要求:(1)分别统计出其中英文字母数和空格数及整篇文章总字数;(2)统计某一字符串在文章中出现的次数,并输出该次数;(3)删除某一子串,并将后面的字符前移。存储结构使用线性表,分别用几个子函数实现相应的功能;输入数据的形式和范围:可以输入大写、小写的英文字母、任何数字及标点符号。输出形式:(1)分行输出用户输入的各行字符;(2)分4行输出全部字母数、数字个数、空格个数、文章总字数(3)输出删除某一字符
22、串后的文章;一概要设计1.定义结构体struct line,文本行采用顺序存储,行与行之间采用链式存储。二流程图具体操作输出删除后的文章删除这一子串统计字母、数字、空格、某一字符串的个数以及文章总字数输出文字查找某一字串输入文字统计个数主函数开始三测试结果四源代码#include #include typedef struct line char *data; struct line *next; LINE; /创建列表,向里面输入文本数据/向屏幕输出文字void OutPut(LINE * &head) LINE *p=head; /头指针 printf(输入的文章为:n); do /执行
23、printf(%sn,p-data); while(p=p-next)!=NULL); /遍历列表printf(n); void menu() /主菜单函数 printf(*文章编辑*n); printf(*n); printf(1.统计文章中全部英文字母数 n); printf(2.统计文章中空格数 n); printf(3 .统计文章中数字个数 n); printf(4.统计文章总字数 n); printf(5.统计指定字符串在文章中出现的次数 n); printf(6.删除指定字符串 n); printf(*n); void Create(LINE * &head) printf (请输
24、入一篇文章,以ctrl+E(E)结尾(每行最多输入80个字符):n); LINE *p=new LINE; /为链表建立一个附加表头指针 head=p; /附给表头指针 char tmp100; while(1) gets(tmp); /输入字符串if(strlen(tmp)80) printf(每行最多输入80个字符); break; if(tmp0=5)break; /如果发现输入E则输入退出 p=p-next=new LINE; /为结点申请新的存储空间p-data=new charstrlen(tmp)+1; /为结点分配空间 strcpy(p-data,tmp); if(tmpstr
25、len(tmp)-1=5) /除去最后一个控制符E p-datastrlen(tmp)-1=0; break; p-next=NULL; /最后一个指针为空 head=head-next; OutPut(head); printf(n); menu(); /统计英文字母void CountLetter(LINE * &head) LINE *p=head; int count=0; do int Len=strlen(p-data); /计算当前data中的数据元素个数for(int i=0;idatai=a&p-dataidatai=A&p-datainext)!=NULL); /遍历链表
26、printf(全部英文字母数%d n, count);/返回文章里 printf(n); menu(); void CountNumber(LINE * &head) LINE *p=head; int count=0; do int Len=strlen(p-data); for(int i=0;idatai=48 & p-datainext)!=NULL); printf(文章中字母数为:%d n,count); printf(n); menu(); void CountSpace(LINE * &head) LINE *p=head; int count=0; do int Len=st
27、rlen(p-data); for(int i=0;idatai=32)count+; while(p=p-next)!=NULL); printf(文章中空格数为: %d n, count); printf(n); menu(); void CountAll(LINE * &head) LINE *p=head; int count=0; do count+=strlen(p-data); while(p=p-next)!=NULL); printf(文章总字数%d n,count); printf(n); menu(); void FindString(LINE * &head) LINE
28、 *p=head; int count=0; int len1=0; int len2; int i,j,k; char str120; printf(n); printf(请输入要统计的字符串:); scanf(%s,str1); len2=strlen(str1); do len1=strlen(p-data); for(i=0;idatai=str10) k=0; for(j=0;jdatai+j=str1j) k+; if(k=len2) count+;i=i+k-1; while(p=p-next)!=NULL);/遍历列表 printf(该字符串在文中出现的次数: %d n,cou
29、nt); printf(n); menu(); /删除指定的字符串void delstringword(char *s,char *str)/*s为输入的字符串,*str为将要删除的字符串 char *p=strstr(s,str); /从字符串中寻找str第一次出现的位置char tmp80; int len=strlen(s); int i=len-strlen(p); int j=i+strlen(str); int count=0; for(int m=0;mi;m+)tmpcount+=sm; for(int n=j;ndata,str)!=NULL)delstringword(p-data,str); while(p=p-next)!=NULL); printf(删除指定字符串后的文章为: n); /OutPut(head); printf(n); menu(); void main() LINE *head; int i; Create(head); for(;) /for 循环 printf(