课程设计报告.docx
《课程设计报告.docx》由会员分享,可在线阅读,更多相关《课程设计报告.docx(40页珍藏版)》请在冰豆网上搜索。
课程设计报告
《数据结构》课程设计
-------------数据结构演示系统
课程设计报告
学院
专业
班级
学号
姓名
完成日期
一,------------需求分析-----------------
二,------------概要设计-----------------
三,------------详细设计-----------------
四,------------调试分析-----------------
五,------------测试结果-----------------
六,------------设计总结-----------------
七,------------参考文献-----------------
八,------------附录程序-----------------
一,课程设计题目
数据结构演示系统1
(1)、顺序表的插入、删除和合并等基本操作
(2)、利用插入运算建立链表;实现链表的查找、删除、计数、输出等功能以及有序链表的合并。
(3)、串的模式匹配(包括求next和nextval的值)。
2程序模块的功能要求
(1)输入的形式和输入值的范围
(2)顺序表和链表的输入形式是整形,输入值的范围是0---9999。
串的输入形式是字符型
(3)输出的形式
顺序表和链表的输出形式是整形;
串的输出形式是字符型。
(4)程序所能达到的功能;
实现顺序表的创建、插入、删除和合并
实现链表的创建、查找、删除、插入、输出。
实现串的模式匹配(包括求next和nextval的值)
(5)测试数据:
包括正确的输入及其输出结果和含有错误的输入及其输出结果
顺序表的输入:
0|11|22|33|44|55|66|77|88|99|
链表输入:
23456789
二,概要设计
1,定义
定义顺序表的结构体
typedefintElemType;
typedefstruct//定义顺序表结构体
{ElemTypedata[MAXSIZE];
intlength;
}SqList;
定义链表的结点结构
typedefstructnode/*定义单链表结点结构类型*/
{
intdata;/*结点的数据域*/structnode*next;/*结点的指针域*/
}linklist;
定义字符串的数组结构
intIndexBF(chars[],chart[],intpos)
{inti,j,m,n;
i=pos-1;j=0;
m=strlen(s);
n=strlen(t);
2,主流程图
3,各模块之间的层次关系
(1)第一层为主界面函数,
第二层为顺序表界面函数、链表界面函数、模式匹配界面函数
第三层为顺序表子函数、链表子函数、模式匹配子函数
(2)主界面函数调用的函数有sqlistfuc()、linklistfuc()、indexfuc()
顺序表界面调用的函数有creatsq()、listinsert()、listdelete()、mergelist()
链表界面调用的函数有creat()、insert()、delete()、search()、、mergelink()、
模式匹配界面调用的函数有creatstring()、KMP(),GetNext(),GetNextval
三,详细设计(见附录)
四、调试分析
1、调试过程中遇到的问题是如何解决的以及对设计与实现的讨论和分析
(1)一开始在在调试程序时遇到了内存错误,最终通过网上查资料找到了出错的原因:
在建立对头指针和队尾指针时没有对指针进行初始化,即没有为指针动态分配空间。
(2指针变量没有初始化。
定义一个指针变量,C编译系统即为它开辟了一个存储空间,如果不进行初始化,则存放的是一个随机地址,它指向的位置就不确定,这在C中是很危险的,如果让一个随机的指针去指向一个随机的地址的话,可能会指向系统的工作区域,破坏数据,从而破坏某种设置,结果可能会使系统运行失常、死机甚至瘫痪。
(3)警告错误太多。
忽略这些警告错误并不影响程序的执行,但有时会影响到程序的执行结果,所以一定要对“WARNING”错误引起足够重视,编程时尽量按照警告信息消除可能影响程序结果的隐患。
编译时当警告错误数目大于某一规定值时(缺省为100)便退出编译器,这时应改变集成开发环境菜单Options/Compiler/Errors中的有关警告错误检查开关为off。
(4)循环语句中,循环控制变量在每次循环未进行改变,使循环成为死循环;或和在循环语句中,不能正确的给循环变量初始化,造成循环次数不合乎要求,得不到正确的结果。
2、算法的时间复杂性
(1)顺序表查找的时间复杂度为:
O
(1)、插入的时间复杂度为:
O(N)、删除的时间复杂度为:
O(N)、合并的时间复杂度为:
O(N)
(2)有序链表插入、查找、删除、合并的时间复杂度分别为为:
O(N)、O
(1)、O
(1)、O(N)
(3)KMP模式匹配的时间复杂度为:
O(N*M)
三,测试结果
运行环境:
C-Free4
1,编译进入主界面
2,输入数字1进入顺序表界面
输入1进行顺序表的创建
输入10个元素,建立一个顺序表
按y继续运行进入顺序表的主界面,按2输出刚建立顺序表
按y继续运行进入顺序表的主界面,按3在顺序表中查找
按y继续运行进入顺序表的主界面,按4在顺序表插入一个元素
按y继续运行进入顺序表的主界面,按5在顺序表删除一个元素
按y继续运行进入顺序表的主界面,按6进行顺序表的合并
按y继续运行进入顺序表的主界面,按0返回主菜单
3,输入数字2进入链表的界面
输入1进行单链表的建立
输入2查找单链表,查找节点位置4
输入3插入节点,节点位置为4,插入的元素为100
输入4删除节点,节点位置为4
输入5输出单链表
输入6返回主菜单
4,输入3进入字符串模式匹配界面
输入1进行BF匹配,匹配的起始位置为4,主串为aaabaaaabaa
输入2进行KMP匹配,起始位置为3
输入3查看Next[]
输入4查看Nextval[]
输入5显示字符串
输入6退出字符串界面,进入主菜单
5,按数字4退出系统。
六、课程设计总结
在开始的时候,很多人都会在编程语言上下苦功,本身并没有错,但是有些人就会产生程序设计的问题就是对编程语言的使用问题的观念,导致他们在进一步学习程序设计的过程中忽略了各种编程思想的吸收和运用,例如有些人很清楚指针的工作原理,却不懂得怎样去利用指针构造并操作完美的链表,他们设计出来的链表也许在删除节点的时候没有释放内存,或许在插入节点的时候因赋值顺序错误导致链表“断裂”,信息丢失,等等。
随着要解决的问题复杂度越来越大,没有经过良好程序设计思想组织起来的代码会出现各种各样的逻辑错误,这种漏洞百出的程序在运行时有时甚至会导致系统崩溃。
所以在对编程语言有了初步了解之后,应该开始重视编程思想的培养,语言很重要,但究竟只是工具,思想才是精髓。
当初我得到《数据结构》一书后,就通过阅读书中的各种数据结构及相应算法的代码来吸收书中的思想。
我认为学习数据结构最能培养一个人对解决程序设计问题的敏感性,其建模思想对解决各种棘手问题有很大帮助,看书的时候要学会思考,例如循环队列的尾节点为何一定要是空的。
当你懂得程序设计问题是类似于数学建模的思想问题后,你才算是真正入门了。
这时,面对程序设计,才不会无所适从。
再进一步提高自己,就要靠做题来验证各种算法思想,前期做题的时候要参考别人的代码,学会从执行效率上分辨出代码的优劣,其次再讨论其实现难度。
之后就是形成自己的风格,有自己的一套解题方式和相应的算法,例如在快排和堆排的具体使用上,能有自己的一套运用方式。
根据具体问题采取自己所熟悉的相应算法来解决,这样的话或许程序的运行效率不是最高效的,但解决问题的速度会比较快,而且这种根据自己风格设计的程序出错率通常会比较低。
七、参考文献
《数据结构》(C语言版)---清华大学出版社----严蔚敏+吴伟民编
《C语言程序设计》(第二版)--中国铁道出版社--李丽娟+马淑萍编
八、附录程序
#include
#include
#include
#include
#include
#include
#include
#include
#defineMAXSIZE100
#defineLENsizeof(linklist)
typedefstructnode/*定义单链表结点结构类型*/
{
intdata;/*结点的数据域*/
structnode*next;/*结点的指针域*/
}linklist;
linklist*Linkcreat()/*建立单链表函数*/
{
intx;
linklist*head,*p,*rear;/*head,rear分别为头指针和尾指针*/
printf("\t你选择的是尾插法建立链表功能:
\n");
head=(structnode*)malloc(LEN);
head->data=-999;/*头指针数据域初始为-999*/
rear=head;/*尾指针的初始值为头结点head*/
printf("\t请输入一组正整数以0结束输入:
\n\t");
scanf("%d",&x);
while(x!
=0)/*输入数据以0为结束标志*/
{
p=(structnode*)malloc(LEN);/*生成一个新结点*/
p->data=x;/*给新结点数据域赋值*/
rear->next=p;/*新结点插入到表尾*rear之后*/
rear=p;/*将尾指针rear指向新的尾结点之后*/
scanf("%d",&x);
}
rear->next=NULL;/*将单链表最后一个结点rear指针域置空*/
printf("\t建立链表成功!
\n");
return(head);
}
voidLinksearch(linklist*head)/*查找单链表结点函数*/
{
intx;
inti=0;
linklist*p;
printf("\t你选择的是查找功能:
\n");
printf("\t请输入要查找节点的值:
");
scanf("%d",&x);
p=head;/*从头结点开始扫面*/
while((p->next!
=NULL)&&(p->data!
=x))/*循环判断查找数据*/
{
p=p->next;/*扫描下移*/
i++;/*数据位置后移*/
}
if(p->data==x)/*如果查找成功输出数据所在位置*/
{
printf("\t查找成功!
\n");
printf("\t输出查找的数据所在位置为:
%d\n",i);
}
elseprintf("\t查找结点不存在!
\n");
}
linklist*Linkinsert(linklist*head)/*单链表结点插入函数*/
{
intx,i,j=1;
linklist*s,*q;
printf("\t你选择的是尾插法插入功能:
\n");
printf("\t请输入要插入的位置:
");
scanf("%d",&i);
printf("\t请输入要插入的数据:
");
scanf("%d",&x);
s=(structnode*)malloc(LEN);/*建立插入数据的结点*/
s->data=x;/*给新结点数据域赋值*/
for(q=head;(q!
=NULL)&&(j<=i-1);j++)/*寻找结点要插入的位置q*/
q=q->next;/*指针后移指向下一个结点*/
if(q!
=NULL)
{
printf("\t插入成功!
\n");
s->next=q->next;/*新结点s后继指向原q结点的后继*/
q->next=s;/*q结点的后继指向新结点s*/
}
elseprintf("\t插入失败!
\n");
return(head);
}
linklist*Linkdelete(linklist*head)/*删除单链表结点函数*/
{
linklist*p,*q;
inti,j=1;/*j为结点计数变量初始为1*/
printf("\t输入要删除的位置:
");/*输入删除的位置*/
scanf("%d",&i);
p=head;
while((p->next!
=NULL)&&(j
{
p=p->next;
j++;
}
if(p->next!
=NULL)/*若该结点存在删除该结点*/
{
q=p->next;/*p的后继地址赋给q*/
printf("\t删除成功!
\n");
printf("\t删除的数据为:
");
printf("%d\n",q->data);/*输出删除结点数据*/
p->next=q->next;/*原始p结点后继指向q删除结点的后继*/
free(q);/*释放删除结点空间q*/
}
elseprintf("\t删除失败!
");
return(head);
}
voidLinkprint(linklist*head)/*输出单链表函数*/
{
linklist*p;
p=head;
if(p==NULL)/*如果表为空输出失败信息*/
printf("\t输出失败!
\n");
printf("\t输出链表为:
");
while(p->next!
=NULL)/*从表头开始循环输出*/
{
p=p->next;/*指针后移指向下一个结点*/
printf("%3d",p->data);
}
printf("\n");
}
intSelect()/*菜单显示函数*/
{
intk;
printf("***********************2.链表操作******************\n");
printf("\t1.建立单链表\n");
printf("\t2.查找单链表\n");
printf("\t3.插入结点\n");
printf("\t4.删除结点\n");
printf("\t5.输出单链表\n");
printf("\t6.退出\n");
do{
printf("\t请输入选择的功能:
");
scanf("%d",&k);/*输入选择的功能*/
printf("-------------------------------\n");
}while((k<1)||(k>6));
return(k);
}
typedefintElemType;
typedefstruct//定义顺序表结构体
{
ElemTypedata[MAXSIZE];
intlength;
}SqList;
voidInitList(SqList&L)
{
L.length=0;
}
voidCreatSqlist(SqList&L,intn)
{
inti,k=0,j=0,x=1;
intflag=0;//设置整数判别的标志位
for(i=0;i{
charstr[4];
char*ptr=str;
printf("*");
printf("请输入No.%d元素的数值(四位正整数,回车键结束操作):
",i+1);
scanf("%s",str);
while(*ptr)//检验输入的是否是整数
{
if(!
isdigit(*ptr++))//调用了isdigit()函数
{
flag=1;
break;//一个非数字的输入、输入错误
}
}
if(flag==0)//是整数时
{
while(str[j]!
='\0')
{
j++;
k++;
}
k--;
L.data[i]=0;
for(j=k;j>-1;j--)
{
L.data[i]+=(str[j]-'0')*x;
x*=10;
}
x=1;
if(L.data[i]<0||L.data[i]>9999||int(L.data[i])!
=L.data[i]||L.data[i]<0)
{
i=i-1;
printf("请重新输入正确数据!
\n");
}
}
else//不是整数时
{
i=i-1;
printf("请重新输入正确数据!
\n");
}
for(j=4;j>0;j--)
{
str[j]='\0';
}
k=0;
}
L.length=n;
getchar();
}
/*voidBubbleSort(SqList*L)//冒泡排序
{
inti,j;
ElemTypet;
SqList*p=L;
for(j=0;jlength-1;j++)
for(i=0;ilength-j-1;i++)
if(p->data[i]>p->data[i+1])
{
t=p->data[i];
p->data[i]=p->data[i+1];
p->data[i+1]=t;
}
}*/
intOutput(SqListL)//输出表
{
inti;
printf("顺序表为:
\n");
for(i=0;i{
if(i%5==0)//按每行5个输出
printf("|\n\n");
printf("|");
printf("%6d",L.data[i]);
}
printf("|");
if(L.length==0)
return0;
else
return1;
}
intGetElem(SqListL,inti)
{
if(i<0||i>=L.length)
return-9999;
else
returnL.data[i];
}
intLocateElem(SqListL,ElemTypex)
{
intk=0;
while(k=x)
k++;
if(kreturnk;
else
return-1;
}
intInsert(SqList&L,ElemTypex,inti)
{
intk;
if(i<0||i>L.length||L.length==MAXSIZE)
return0;
else
{
for(k=L.length;k>=i;k--)
L.data[k]=L.data[k-1];
L.data[i]=x;
L.length=L.length+1;
}
return1;
}
intDelete(SqList&L,inti)
{
intk;
if(i<0||i>=L.length)
return0;
else
{
for(k=i;kL.data[k]=L.data[k+1];
L.length--;
}
return1;
}
voidMergeList(SqListla,SqListlb,SqList&lc)
{
inti=0,j=0,k=0;
while(ilc.data[k++]=la.data[i++];
while(jlc.data[k++]=lb.data[j++];
lc.length=k;
/*while(iif(la.data[i]lc.data[k++]=la.data[i++];
elseif(la.data[i]>lb.data[j])
lc.data[k++]=lb.data[j++];
else
{
lc.data[k++]=lb.data[j++];
i++;
}
while(ilc.data[k++]=la.data[i++];
while(jlc.data[k++]=la.data[j++];
lc.length=k;
*/
}
voidtitle(void)
{
inti;
for(i=0;i<10;i++)
printf("");
for(i=0;i<32;i++)
printf("*");
printf("\n");
}
intIndexBF(chars[],chart[],intpos)
{inti,j,m,n;
i=pos-1;j=0;
m=strlen(s);
n=strlen(t);
while(i{if(s[i]==t[j])
{++i;++j;}
else{i=i-j+1;j=0;}
}
if(j>=n)
returni-n+1;
else
return-1;
}
voidGetNext(chart[],intnext[])