数据结构协同作业试验项目文档第二组.docx
《数据结构协同作业试验项目文档第二组.docx》由会员分享,可在线阅读,更多相关《数据结构协同作业试验项目文档第二组.docx(24页珍藏版)》请在冰豆网上搜索。
![数据结构协同作业试验项目文档第二组.docx](https://file1.bdocx.com/fileroot1/2023-1/21/f0ddafd8-49cc-4386-a364-f88448545130/f0ddafd8-49cc-4386-a364-f884485451301.gif)
数据结构协同作业试验项目文档第二组
上海交通大学网络教育
数据结构协同作业实验
线性表
1顺序表操作验证2
1.1实验目的2
1.2实验内容2
2一元多项式相加实验2
3开发环境2
4算法设计介绍3
4.1设计思路3
4.2详细设计6
5界面流程展示7
6检查及测试报告9
6.1检查报告9
6.2测试报告9
7附程序源代码10
7.1一元多项式验证:
10
7.2顺序表操作验证:
17
1顺序表操作验证
1.1实验目的
(1)掌握线性表的顺序存储结构;
(2)验证顺序表及其基本操作的实现;
(3)掌握数据结构及算法的程序实现的基本方法。
1.2实验内容
(1)建立含有若干个元素的顺序表;
(2)对已建立的顺序表实现插入、删除、查找等基本操作。
2一元多项式相加实验
已知A(x)=a0+a1x+a2x2+……+anxn和B(x)=b0+b1x+b2x2+……+amxm,并在A(x)和B(x)中指数相差很多,求A(x)=A(x)+B(x)。
3开发环境
软件平台:
WindowsXP
软件环境:
MicrosoftVisualC++6.0
最低硬件配置:
内存64MB或以上、硬盘3.2G或以上
4算法设计介绍
4.1设计思路
分析:
1.存储结构分析
根据一元多项式的特点,要表示一个多项式,只要存储第i项以及ai的值,并且如果ai为0的话,该项就不用存储了,从而减少一个存储空间。
在线性表中可以通过顺序和链式存储,并用Ti表示一个数据项Ti=(ai,i)。
下面以图示表示两种存储结构(假设a2=0)。
图1顺序存储表
图2单链表存储
以上两个图可知,在存储空间分配量上两种结构是一致的,但如果两多项式相加的话需要频繁的做插入操作,顺序表的结构特性决定了插入操作的时间复杂度为O(n/2),链式表的时间复杂度为O
(1),并且如果存储的是一个排好序的多项式的话,不需要双向查找,因此选择单链表存储。
2.相加算法分析
首先,由于两个多项式A(x)和B(x)的指数相差非常多,因此一定要把输入的多项式按照指数i排好序,防止过高的查找时间复杂度;其次,两个AB多项式同时从head开始查找,AB指数i相同的计算相加ai值存入A表,并且回收不需要的B空间,指数不同的,B指数小的节点插到A指数大的前面。
以此往后推移。
其时间复杂度为O(n)。
举例:
A(x)=2+3x+1x3
B(x)=1+3x+2x2+2x4+12x7+32x8+42x11+2x12
整个相加过程如下:
见注释1
图3初始化后的A(x)pA=headA
图4初始化后的B(x)pB=HeadB->next
第一步:
图5A(x)pA->next系数+pB系数
图6B(x)pA->next指数0与pB指数0相等freepB所指节点
第二步与第一步做法一致
第三步将pB的节点插入pA后
第四步pA->next指数小于pB指数,pA=pA->next,pB不动
第五步pA没有后继节点,直接把pB的所有节点接到pA后即可
4.2详细设计
a)数据结构
typedefstructterm{
floatcoef;//系数
intexpn;//指数
structterm*next//指向下一节点
}term
b)输入输出
输入:
两个多项式A,B
输出:
A+B
样式:
输入一元多项式的项数
2
请依次输入非零2个非零项,请注意输入格式
22
33
3X^3+2X^2
1~4(+-*退出)4个选项
再输入一元多项式的项数
3
请依次输入非零3个非零项,请注意输入格式
22
33
44
3X^3+2X^2+4X^4+3X^3+2X^2=4X^4+6X^3+4X^2
c)函数原型
主函数:
voidmain()
输入函数:
InputPolynomial(LinkList&p)
多项式相加函数:
term*APolyn(term*Pa,term*Pb)
多项式相减函数:
term*BPolyn(term*Pa,term*Pb)
多项式相乘函数:
term*CPolyn(term*Pa,term*Pb)
输出函数:
voidPrintfPoly(term*P)
5界面流程展示
第一步:
先输入第一个“一元多项式的项数”
第二步,根据一元多项式的项数,输入非零项。
注意输入格式,系数和指数之间要有空格。
第三步,选择要进行的运算方式编码
第四步,再输入第二个“一元多项式的项数”,方式如第二步一致,最后回车进行运算
6检查及测试报告
6.1检查报告
检查名称
检查任务
完成情况
是
否
安装
程序运行环境已经正确设定
√
程序代码检查
程序单位首部有程序说明和修改备注
√
变量、过程、函数命令符合规则
√
程序中有足够的说明信息
√
修改注释符合要求
√
类库的使用符合要求
√
画面及报表格式检查
画面及报表格式符合规定需求
√
程序命名符合格式需求
√
画面和报表的字段位置和宽度与设计文档一致
√
6.2测试报告
测试名称
测试任务
完成情况
是
否
功能键、触发键、按钮、菜单、选择项功能正确
√
数据项关联及限制功能正确
√
设计文档规定的其他功能
正确性测试
读/写/删除操作结果正确
√
各种组合条件之查询或报价正确
√
设计文档规定的其他操作
可靠性测试
非法键容错测试
√
异常字符容错测试
√
程序副作用检查
√
残留文件检查
√
效率测试
输入画面效率测试
报表及查询效率测试
其他测试
7附程序源代码
7.1一元多项式验证:
#include
#include
#include
typedefstructterm//项的表示,多项式的项作为LinkList的数据元素
{
floatcoef;//系数
intexpn;//指数
structterm*next;
}term;
term*CreatPolyn(term*P,intm)//输入m项的系数和指数,建立表示一元多项式的有序链表P
{
if(m<=0)returnNULL;
term*h=P=(term*)malloc(sizeof(term)),*q;
P->coef=0.0;
inti;
printf("依次输入%d个非零项,请注意输入格式,系数和指数之间要有空格,ex:
2231\n",m);
for(i=1;i<=m;++i)//依次输入m个非零项
{
scanf("%f%d",&P->coef,&P->expn);
if(P->coef)
q=P;
P=P->next=(term*)malloc(sizeof(term));
}
q->next=NULL;
free(P);
returnh;
}//CreatPolyn
term*selsort(term*h)
{
term*g,*p,*q;
if(!
h)returnNULL;
floatf;
inti,fini=1;
for(g=h;g->next&&fini;g=g->next)
{
fini=0;
for(p=h,q=h->next;q;p=p->next,q=q->next)
if(p->expnexpn)
{
f=p->coef;i=p->expn;
p->coef=q->coef;p->expn=q->expn;
q->coef=f;q->expn=i;
fini=1;
}
}
for(g=h,p=g->next;p;)
if(g->expn==p->expn)
{
g->coef+=p->coef;
g->next=p->next;
q=p;
p=p->next;
free(q);
}elseif(g->next)
{
g=g->next;
p=p->next;
}
returnh;
}
voidPrintfPoly(term*P)
{
term*q=P;
if(!
q)
{
putchar('0');
return;
}
if(q->coef!
=1)
{
printf("%g",q->coef);
if(q->expn==1)putchar('X');
elseif(q->expn)printf("X^%d",q->expn);
}
elseif(!
q->expn)putchar('1');
elseif(q->expn==1)putchar('X');
elseprintf("X^%d",q->expn);
q=q->next;
while(q)
{
if(q->coef>0)putchar('+');
if(q->coef!
=1)
{
printf("%g",q->coef);
if(q->expn==1)putchar('X');
elseif(q->expn)printf("X^%d",q->expn);
}
elseif(!
q->expn)putchar('1');
elseif(q->expn==1)putchar('X');
elseprintf("X^%d",q->expn);
q=q->next;
}
}
Compare(term*a,term*b)
{
if(a->expnexpn)return-1;
if(a->expn>b->expn)return1;
return0;
}
term*APolyn(term*Pa,term*Pb)//多项式加法:
Pa=Pa+Pb,利用两个多项式的结点构成"和多项式"。
{
term*h,*qa=Pa,*qb=Pb,*p,*q;
floatsum;
h=p=(term*)malloc(sizeof(term));
p->next=NULL;
while(qa&&qb)//Pa和Pb均非空
{
switch(Compare(qa,qb))
{
case-1:
//多项式PA中当前结点的指数值小
p->next=qb;
p=qb;
qb=qb->next;
break;
case0:
//两者的指数值相等
sum=qa->coef+qb->coef;
if(sum!
=0.0)//修改多项式PA中当前结点的系数值
{
p->next=qa;
qa->coef=sum;
p=qa;
qa=qa->next;
}
else//删除多项式PA中当前结点
{
q=qa;
qa=qa->next;
free(q);
}
q=qb;
qb=qb->next;
free(q);
break;
case1:
//多项式PB中当前结点的指数值小
p->next=qa;
p=qa;
qa=qa->next;
break;
}//switch
}//while
if(Pa)p->next=qa;//链接Pa中剩余结点
if(Pb)p->next=qb;//链接Pb中剩余结点
q=h;
h=h->next;
free(q);
returnh;
}//APolyn
term*A(term*Pa,term*Pb)
{
intn;
puts("再输入一元多项式的项数");
scanf("%d",&n);
Pb=CreatPolyn(Pb,n);
Pb=selsort(Pb);
PrintfPoly(Pa);
if(Pb&&Pb->coef>0)printf("+");
PrintfPoly(Pb);
Pa=APolyn(Pa,Pb);
printf("=");
Pa=selsort(Pa);
PrintfPoly(Pa);
returnPa;
}
term*BPolyn(term*Pa,term*Pb)//多项式减法:
Pa=Pa-Pb,利用两个多项式的结点构成"差多项式"。
{
term*p=Pb;
while(p)
{
p->coef*=-1;
p=p->next;
}
returnAPolyn(Pa,Pb);
}//BPolyn
term*B(term*Pa,term*Pb)
{
intn;
puts("再输入一元多项式的项数");
scanf("%d",&n);
Pb=CreatPolyn(Pb,n);
Pb=selsort(Pb);
PrintfPoly(Pa);
printf("-");
putchar('(');PrintfPoly(Pb);putchar(')');
Pa=BPolyn(Pa,Pb);
printf("=");
Pa=selsort(Pa);
PrintfPoly(Pa);
returnPa;
}
term*CPolyn(term*Pa,term*Pb)//多项式乘法:
Pa=Pa*Pb,利用两个多项式的结点构成"积多项式"。
{
if(!
Pb)returnNULL;
term*pa=Pa,*p,*q,*r,*s,*t;
r=p=(term*)malloc(sizeof(term));
while(pa){
p->coef=pa->coef;
p->expn=pa->expn;
q=p;
p=p->next=(term*)malloc(sizeof(term));
pa=pa->next;
}
q->next=NULL;
free(p);
pa=Pa;
t=s=(term*)malloc(sizeof(term));
while(pa){
q=s;
s=s->next=(term*)malloc(sizeof(term));
pa=pa->next;
}
q->next=NULL;
free(s);
pa=Pa;
while(pa){
pa->coef*=Pb->coef;
pa->expn+=Pb->expn;
pa=pa->next;}
Pb=Pb->next;
while(Pb)
{
p=r;
s=t;
while(p)
{
s->coef=p->coef*Pb->coef;
s->expn=p->expn+Pb->expn;
p=p->next;
s=s->next;
}
Pa=APolyn(Pa,t);
Pb=Pb->next;
}
returnPa;
}//CPolyn
term*C(term*Pa,term*Pb)
{
intn;
puts("再输入一元多项式的项数");
scanf("%d",&n);
Pb=CreatPolyn(Pb,n);
Pb=selsort(Pb);
putchar('(');PrintfPoly(Pa);putchar(')');
printf("*");
putchar('(');PrintfPoly(Pb);putchar(')');
printf("=");
Pa=CPolyn(Pa,Pb);
Pa=selsort(Pa);
PrintfPoly(Pa);
returnPa;
}
voidmain()
{
term*M,*N;
chars[2];
inti,n;
puts("一元多项式计算:
\n输入一元多项式的项数");
scanf("%d",&n);
M=CreatPolyn(M,n);
M=selsort(M);
PrintfPoly(M);
p:
puts("\n1:
加\n2:
减\n3:
乘\n4:
退出");
getchar();
q:
gets(s);
if(s[1]!
='\0'||!
isdigit(*s))
{
puts("输入有误,请重新输入!
");gotoq;
}
i=*s-48;
switch(i)
{
case1:
M=A(M,N);gotop;;
case2:
M=B(M,N);gotop;;
case3:
M=C(M,N);gotop;
case4:
break;
default:
puts("输入有误,请重新输入!
");gotoq;
}
}
7.2顺序表操作验证:
#include
#include
#include
typedefstructterm//项的表示,多项式的项作为LinkList的数据元素
{
intexpn;//指数
structterm*next;
}term,*LinkList;
term*CreatPolyn(term*P,intm)//输入m项的系数和指数,建立表示一元多项式的有序链表P
{
if(m<=0)returnNULL;
term*h=P=(term*)malloc(sizeof(term)),*q;
inti;
printf("输入整数要有空格,ex:
2231\n",m);
for(i=1;i<=m;++i)//依次输入m个非零项
{
scanf("%d",&P->expn);
q=P;
P=P->next=(term*)malloc(sizeof(term));
}
q->next=NULL;
free(P);
returnh;
}//CreatPolyn
voidFindData(term*p,intdata)
{
term*q=p;
while(q)
{
if(q->expn==data)
{
break;
}else
{
q=q->next;
}
}
if(q)
{
printf("查找到数据\n");
}
}
term*DeleteData(LinkList*p,intdata)
{
LinkList*q;
term*h;
term*r;
q=p;
h=r=*p;
if(!
q)
{
printf("连表为空");
returnh;
}
while(*q)
{
if((*q)->expn==data)
{
term*t=(*q);
r->next=t->next;
free(t);
break;
}else
{
r=*q;
(*q)=(*q)->next;
}
}
returnh;
}
voidPrintList(term*h)
{
printf("连表数据:
\n");
while(h)
{
printf("%d",h->expn);
h=h->next;
}
}
term*InsertData(LinkList*p,intfData,intiData)
{
LinkList*q;
term*r,*h;
term*data;
q=p;
r=*q;
h=*q;
if(!
q)
{
printf("连表为空");
returnh;
}
while((*q))
{
if((*q)->expn==fData)
{
data=(term*)malloc(sizeof(term));
data->expn=iData;
data->next=(*q);
r->next=data;
break;
}else
{
r=*q;
(*q)=(*q)->next;
}
}
returnh;
}
voidmain()
{
term*M,*N;
chars[2];
inti,n,data1,data2;
puts("请输入数据个数");
scanf("%d",&n);
M=CreatPolyn(M,n);
PrintList(M);
p:
puts("\n1:
查找\n2:
删除\n3:
插入\n4:
退出");
getchar();
q:
gets(s);
if(s[1]!
='\0'||!
isdigit(*s))
{
puts("输入有误,请重新输入!
");goto