王勤为的课程设计报告修改.docx
《王勤为的课程设计报告修改.docx》由会员分享,可在线阅读,更多相关《王勤为的课程设计报告修改.docx(42页珍藏版)》请在冰豆网上搜索。
王勤为的课程设计报告修改
数据结构课程设计
报告封面
1.班级:
信息安全02班2.学号:
0909091723
3.姓名:
王勤为4.所选题目:
一号题
5.完成日期:
2011/7/1
课程设计报告目录
八.附录:
源代码
一.需求分析
1.建立顺序表储存结构,演示插入、删除和合并等基本操作。
2.利用插入运算建立链表;实现链表的查找、删除、计数、输出等功能以及有序链表的合并。
3.建立串的储存结构,演示串的模式匹配(包括求next和nextval的值),需要包含串的输入输出。
4.要求要有良好的界面,每个系统组织到一个统一的界面中。
5.程序能够良好运行,输入合理的数据能够输出正确的结果,且操作可重复实现。
二.概要设计(c语言)
1.概要流程图
2.储存类型说明
①顺序表:
内存动态分布结构
typedefstructList{
int*base;//地址
intlenth;//表长(元素个数)
intlistsize;}Sqlist;//listsize当前储存容量
链表:
带头结点的单向链表
typedefstructLNode{
intdate;//数据类型
structLNode*next;//指向下一节点的指针
}*link;//结点类型
串:
用定长的数组来储存
typedefstruct{
chardata[MAXSTRING+1];//0号单元储存其长度
}SString;//串结构体说明
三.详细分析
1.顺序表相关分析
基本函数
初始化函数:
initlist1(Sqlist&L)
插入元素函数:
Listinsert1(Sqlist&L,inti,inte)
输入元素函数:
Listputin1(Sqlist&L,intn)
删除元素函数:
Deletelist1(Sqlist&L,inti)
销毁函数:
Clearlist1(Sqlist&L)
合并函数:
Mergelist1(Sqlist&L1,Sqlist&L2)
辅助函数:
显示界面函数paint1()
显示顺序表元素的函数Displaylist1(Sqlist&L)
关键函数的算法分析:
初始化函数initlist1(Sqlist&L):
分配空间——从键盘获得要输入元素个数——调用Listputin1()函数进行元素输入——初始化完毕。
intinitlist1(Sqlist&L){
L.base=(int*)malloc(MAX_SIZE*sizeof(int));
if(!
L.base)return(0);
L.lenth=0;L.listsize=0;
printf("请输入要输入元素的个数:
");
intn;scanf("%d",&n);
Listputin1(L,n);
printf("初始化成功!
");
}
插入元素函数:
Listinsert1(Sqlist&L,inti,inte):
重新分配空间——用q指向插入位置的前一个——q之后的元素右移,空出插入位置——插入元素e。
intListinsert1(Sqlist&L,inti,inte){
if(!
L.base)return(0);
if(i<1||i>L.lenth+1)return(0);//插入位置不合理退出
int*newbase,*q,*p;
if(L.lenth>L.listsize){
newbase=(int*)realloc(L.base,(L.listsize+SIZE_increase)*(sizeof(int)));
if(!
newbase)return(0);
L.base=newbase;
L.listsize+=SIZE_increase;
}
q=&(L.base[i-1]);
for(p=&(L.base[L.lenth-1]);p>=q;p--)*(p+1)=*p;
*q=e;
L.lenth++;
return
(1);
}
输入元素函数Listputin1(Sqlist&L,intn):
其实质就是不停的调用插入函数,从键盘获得要插入的元素个数n,然后进行n次插入操作
intListputin1(Sqlist&L,intn){
if(!
L.base)return(0);
inti,e;
printf("请一次输入所有元素:
");
for(i=1;i<=n;i++){scanf("%d",&e);Listinsert1(L,i,e);}
删除元素函数Deletelist1(Sqlist&L,inti):
用q指向插入位置i的后一个——p之后的元素左移——删除完毕。
intDeletelist1(Sqlist&L,inti){
if(!
L.base)return(0);
inte;int*q,*p;e=L.base[i-1];
q=&(L.base[L.lenth-1]);
for(p=&(L.base[i]);p<=&(L.base[L.lenth-1]);p++)*(p-1)=*p;//删除位置之后的元素左移
L.lenth--;
return(e);
}
合并函数Mergelist1(Sqlist&L1,Sqlist&L2):
其实质是把L2中的元素插入到L1中去,通过两重循环检查L2中的元素在L1中是否存在,如果存在就不插入,否则就插入L1中。
intMergelist1(Sqlist&L1,Sqlist&L2){
if((!
L1.base)||(!
L2.base))exit(0);
inti,m;
for(i=0;im=0;
while(L2.base[i]!
=L1.base[m]&&m<=L1.lenth)m++;
if(L2.base[i]==L1.base[m])continue;
Listinsert1(L1,L1.lenth+1,L2.base[i]);
}
return
(1);
}
2.链表相关分析
基本函数
初始化函数Initlist2(link&L,intn)
排序函数list_sort2(link&L,intn)
插入函数ListInsert2(link&L,inti,inte)
删除函数ListDelete2(link&L,inti)
查找函数ElemIndex2(linkL,inti)
计数函数get_num(linkL)
合并函数MergeList2(linkLa,linkLb)
辅助函数:
显示界面函数paint2()
显示顺序表元素的函数Display2(linkL)
关键函数的算法分析:
初始化函数Initlist2(link&L,intn)
分配一个节点空间为头结点L——L->next赋值为空——头插法建表——获取要插入元素的个数n——进行n次插入元素操作——进行排序,调用排序函数list_sort2(L,n),使按非递增方式排列。
Initlist2(link&L,intn){
linkp;
L=(link)malloc(sizeof(LNode));
L->next=NULL;
if(!
L)exit(-1);
printf("初始化链表成功!
");
printf("请依次输入所有元素!
");
inti;
for(i=n;i>0;i--){
p=(link)malloc(sizeof(LNode));
scanf("%d",&(p->date));
p->next=L->next;
L->next=p;}
list_sort2(L,n);//初始化的同时排序
}
排序函数list_sort2(link&L,intn):
排序思想为冒泡排序
list_sort2(link&L,intn){
linkp,r;//p指向当前元素,r指向后一元素
inti;
for(i=1;i<=n;i++){p=L->next;
r=p->next;
while(r&&p)
{if((p->date)>(r->date)){intq;
q=p->date;
p->date=r->date;
r->date=q;
}//大的元素往后移,即进行交换操作
if((p->date)==(r->date)){p->next=r->next;free(r);i++;}
p=p->next;
if(p)r=p->next;//有相等的元素就删除一个
}//while
}//for
}//排序函数
插入函数ListInsert2(link&L,inti,inte)
通过循环使p指向插入位置的前一个元素——给新节点q分配空间——修改指针使q插入到p之后——插入完毕!
ListInsert2(link&L,inti,inte){
intj;linkp;linkq;
p=L;j=0;
if(!
(p->next)||j>i-1)
{printf("发生错误!
");return(0);}//插入位置不合理
while(p->next&&jp=p->next;
++j;
}//使p指向插入位置的前一个
q=(link)malloc(sizeof(LNode));
q->date=e;
q->next=p->next;//修改指针
p->next=q;
printf("插入成功!
");
}
删除函数ListDelete2(link&L,inti)
算法思想同前一函数差不多
ListDelete2(link&L,inti){
linkp,q;
intj;
p=L;j=0;
while(p->next&&jp=p->next;
++j;
}//p指向要删除元素的前一个
if(!
(p->next)||j>i-1){exit(-1);printf("发生错误!
");}
q=p->next;p->next=q->next;free(q);
printf("已删除元素");
}
计数函数get_num(linkL)
用j做为计数器——通过循环直到表尾,每次j都加一——
最终j为表中元素的个数
get_num(linkL){
linkp;intj;//j为计数器
p=L;j=0;
while(p->next){p=p->next;j++;}
return(j);
}
合并函数MergeList2(linkLa,linkLb)
其实质仍然是把Lb中的元素插入到L1中去——把La的空间看做一个新表Lc——不断移动两个指针比较两表中元素的大小——小的元素插入到L中——相同的元素摒弃——当一个表中元素到了末尾时,把另一个表中的剩余元素插入Lc中。
MergeList2(linkLa,linkLb){
linkpa,pb,Lc,pc;
pa=La->next;
pb=Lb->next;
Lc=pc=La;
while(pa&&pb){
if(pa->datedate){
pc->next=pa;pc=pa;pa=pa->next;
}
elseif(pa->date=pb->date){
pc->next=pa;pc=pa;pa=pa->next;pb=pb->next;
}//想同的元素摒弃
else{
pc->next=pb;pc=pb;pb=pb->next;
}
}//while
pc->next=pa?
pa:
pb;//插入另一个表中的剩余元素
free(Lb);
3.串相关分析
基本函数
创建串函数Createstr(SString&L)
模式匹配函数Indexstr_kmp(SString&L,SString&T,intpos)
求模式匹配值函数get_next(SString&T)
求模式匹配修正值函数get_nextval(SString&T)
辅助函数
显示界面函数pain3()
关键函数的算法分析
创建串函数Createstr(SString&L)
利用while循环从键盘获得输入值——字符串用#号结束——输入完毕后把输入的字符输出以便检查。
Createstr(SString&L){
inti,m;
charflag;
i=1;
printf("请依次输入各个字符");
while
(1){
scanf("%c",&flag);
if(flag!
='#')
{L.data[i]=flag;++i;
L.data[0]=i-1;}
elsebreak;
}
printf("您输入了以下字符!
");
for(m=1;m
}
模式匹配函数Indexstr_kmp(SString&L,SString&T,intpos)
设立两指针,i指向主串中当前比较字符,j指向模式串中当前比较的字符——比较i和j指向的字符——如果相等,两指针同事后移——如果不相等,j等于next[j]中保存的值——如此反复,直到匹配成功或者主串用尽。
Indexstr_kmp(SString&L,SString&T,intpos){
inti,j;
i=pos;j=1;
while(i<=L.data[0]&&j<=T.data[0]){
if(j==0||L.data[i]==T.data[j]){i++;j++;}
elsej=next[j];}
if(j>T.data[0])return(i-T.data[0]);//返回其位置
elsereturn(0);
}
求模式匹配值函数get_next(SString&T)
其实质就是检查模式串中是否存在以下相等关系
p
(1)p
(2)p(3)…..p(k-1)’=’s(i-k+1)s(i-k+2)……s(i-1)
如果存在则next[i]的值为k,不存在则为1,其中next[1]=0
get_next(SString&T){
inti,j;
i=1;next[1]=0;j=0;next[0]=T.data[0];
while(iif(j==0||T.data[i]==T.data[j])
{++i;++j;next[i]=j;}
else
j=next[j];}
}
求模式匹配修正值函数get_nextval(SString&T)
get_nextval(SString&T){
inti,j;
i=1;nextval[1]=0;j=0;nextval[0]=T.data[0];
while(iif(j==0||T.data[i]==T.data[j]){
++i;++j;
if(T.data[i]!
=T.data[j])nextval[i]=j;
elsenextval[i]=nextval[j];
}
elsej=next[j];}
}
四.调试分析
五.测试结果:
上一步中分别对三个模块进行了测试,所有功能都正常实现,说明所用的算法正确无误。
六.课程设计总结:
1.实践最重要,书本上的只是总是相对空泛的,只有实践才能真正掌握知识。
2.课程设计中或多或少遇到了一些困难,有些是算法上的,有些是代码上的。
须得耐心冷静的进行调试,不要已有错误就去请教他人,自己总要有调试程序的能力。
3.这是第一次完成代码量超过五百行的程序,各方面都获得了长足进步,编程的兴趣亦大大增加。
总之感谢学校的与人制度,感谢陈再良教授给予的帮助和培养。
七.参考文献:
清华大学出版社严蔚敏《数据结构c语言版》
清华大学出版社谭浩强《c程序设计》
八.附录:
全部源代码
#include
#include
#defineMAX_SIZE100
#defineSIZE_increase10
#defineMAXSTRING255
intnext[MAXSTRING+1];
intnextval[MAXSTRING+1];
typedefstructList{
int*base;
intlenth;
intlistsize;}Sqlist;
//顺序表结构体说明
typedefstructLNode{
intdate;
structLNode*next;
}*link;////线性表结构体说明
#defineMAXSTRING255
typedefstruct{
chardata[MAXSTRING];
}SString;//串结构体说明
//顺序表的相关函数定义
intListinsert1(Sqlist&L,inti,inte){
if(!
L.base)return(0);
if(i<1||i>L.lenth+1)return(0);
int*newbase,*q,*p;
if(L.lenth>L.listsize){
newbase=(int*)realloc(L.base,(L.listsize+SIZE_increase)*(sizeof(int)));
if(!
newbase)return(0);
L.base=newbase;
L.listsize+=SIZE_increase;
}
q=&(L.base[i-1]);
for(p=&(L.base[L.lenth-1]);p>=q;p--)*(p+1)=*p;
*q=e;
L.lenth++;
return
(1);
}
intListputin1(Sqlist&L,intn){
if(!
L.base)return(0);
inti,e;
printf("请一次输入所有元素:
");
for(i=1;i<=n;i++){scanf("%d",&e);Listinsert1(L,i,e);}
}
intinitlist1(Sqlist&L){
L.base=(int*)malloc(MAX_SIZE*sizeof(int));
if(!
L.base)return(0);
L.lenth=0;
L.listsize=0;
printf("请输入要输入元素的个数:
");
intn;
scanf("%d",&n);
Listputin1(L,n);
printf("初始化成功!
");
}
intDeletelist1(Sqlist&L,inti){
if(!
L.base)return(0);
inte;
int*q,*p;
e=L.base[i-1];
q=&(L.base[L.lenth-1]);
for(p=&(L.base[i]);p<=&(L.base[L.lenth-1]);p++)*(p-1)=*p;//删除位置之后的元素左移
L.lenth--;
return(e);
}
intClearlist1(Sqlist&L){
if(!
L.base)return(0);
inti,m;
m=L.lenth;
for(i=1;i<=m;i++)Deletelist1(L,1);
free(L.base);
return
(1);
}
intDisplaylist1(Sqlist&L){
if(!
L.base){printf("顺序表不存在");exit(0);}
inti;
for(i=0;i<=L.lenth-1;i++)printf("%d",L.base[i]);}
intMergelist1(Sqlist&L1,Sqlist&L2){
if((!
L1.base)||(!
L2.base))exit(0);
inti,m;
for(i=0;im=0;
while(L2.base[i]!
=L1.base[m]&&m<=L1.lenth)m++;
if(L2.base[i]==L1.base[m])continue;
Listinsert1(L1,L1.lenth+1,L2.base[i]);
}
return
(1);
}
voidpaint1(){
system("cls");
putchar('\n');putchar('\n');putchar('\n');
printf("实验一:
顺序表相关操作\n\n");
printf("1.创建顺序表一2.创建顺序表二\n\n");
printf("3.插入元素4.合并两个顺序表\n\n");
printf("5.显示表中元素6.销毁顺序表\n\n");
printf("0.退出\n");
}
intmain1(){
intflag;
SqlistH1,H2;
loop:
paint1();
putchar('\n');
printf("请输入要操作项目的序号:
");
scanf("%d",&flag);
while(flag){
switch(flag){
case1:
initlist1(H1);getchar();getchar();break;
case2:
initlist1(H2);getchar();getchar();break;
case3:
{intnum1,pos1,e;
printf("请输入要操作顺序表的序号,插入元素,插入位置:
");
scanf("%d%d%d",&num1,&e,&pos1);
switch(num1){
case1:
if(Listinsert1(H1,pos1,e))printf("插入成功!
");
getchar();get