实验二.docx
《实验二.docx》由会员分享,可在线阅读,更多相关《实验二.docx(20页珍藏版)》请在冰豆网上搜索。
实验二
实验难度:
A□B√□B-C□C□
序号
学号
姓名
成绩
2013
指导教师
(签名)
学 期:
2014秋季学期
任课教师:
实验题目:
实验二线性表及其应用
小组长:
联系电话:
电子邮件:
完成提交时间:
2014年11月12日
一、【实验构思(Conceive)】(10%)
实验基本思路:
应用链表易于添加和删除的特点,构造抽象数据类型-多项式。
每个节点包含数据域指数和次数,指针域指向下一个节点。
同过相同指数节点之间的操作实现多项式的加,减,相乘,求导等操作。
应用到的相关知识:
1)多项式的基本四则运算及求导算法。
2)带头结点的链表的存储结构。
二、【实验设计(Design)】(20%)
(本部分应包括:
抽象数据类型的定义和基本操作说明,程序包含的模块以及各模块间的调用关系,关键算法伪码描述及程序流程图等)
抽象数据类型的定义:
typedefstructPolynote{
floatcoef;
intexpon;
structPolynote*next;
}*Polyn,Polynote;//定义了数据域和指针域,以及一个指针变量和一个结构体变量。
创建函数时
程序模块:
本次试验中,巧妙设计了一种Insert函数,使得在创建节点时,只需创建头结点,求导和除法每步生成的新节点都可以通过调用Insert函数来插入之前创建的头结点并且按降序排列,用户输入时也可以按任意顺序,都会通过creat函数调用Insert函数来保证降序排列。
加减法的实现则是通过将两个多项式链表相互穿插,返回新生成链表的头结点来实现的,执行adds,minus函数时调用compare函数来实现相同指数项相加减,函数通过调用检错功能强大的print函数输出结果。
关键算法:
Insert函数:
1)voidInsert(Polynp,Polynh){
2)if(p->coef==0)free(p);//系数为零不考虑
3)else{
4)Polynq1,q2;
5)q1=h;q2=h->next;
6)while(q2&&p->exponexpon){//查找插入位置
7)q1=q2;
8)q2=q2->next;
9)}
10)if(q2&&p->expon==q2->expon){//将指数相同相合并
11)q2->coef+=p->coef;
12)free(p);
13)if(!
q2->coef){
14)q1->next=q2->next;
15)free(q2);
16)}
17)}
18)else{//指数为新时将结点插入
19)p->next=q2;
20)q1->next=p;
21)}
22)}
23)}
Print函数:
voidPrintPolyn(PolynP){
Polynq=P->next;
intflag=1;//用作计数器
if(!
q){
putchar('0');//无输出节点时,输出0
printf("\n");
return;
}
while(q){
if(q->coef>0&&flag!
=1)putchar('+');//q的系数为正且不是第一项,就要输出加号。
if(q->coef!
=1&&q->coef!
=-1){//系数非1或-1的普通情况
printf("%3.1f",q->coef);
if(q->expon)printf("X^%d",q->expon);
}
else{
if(q->coef==1){
if(!
q->expon)putchar('1');//系数为1,指数为0,输出1
elseif(q->expon==1)putchar('X');//系指为1,输出X
elseprintf("X^%d",q->expon);
}
if((int)q->coef==-1){//对复数项的处理
if(!
q->expon)printf("-1");
elseif(q->expon==1)printf("-X");
elseprintf("-X^%d",q->expon);
}
}
q=q->next;
flag++;//保证只有在第一项时,flag值为1.
}
printf("\n");
}
三、【实现(Implement)】(30%)
(本部分应包括:
抽象数据类型各操作的具体实现、关键操作的具体算法实现、函数实现,主程序实现等,并给出关键算法的时间复杂度分析。
)
Compare函数的实现:
intcompare(Polyna,Polynb){//不同的返回值是为了配合switch函数对节点进行排序。
if(a&&b){
if(a->expon>b->expon)return1;
elseif(a->exponexpon)return-1;
elsereturn0;
}
elseif(!
a&&b)return-1;
elsereturn1;
}
Creat函数的实现:
PolynCreatePolyn(Polynhead,intm){//由用户规定多项式的项数,m值帮助程序计数,最后调用Insert函数来降序排序,返回多项式的头结点。
inti;//用来计数
Polynp;
p=head=(Polyn)malloc(sizeof(structPolynote));
head->next=NULL;
for(i=0;ip=(Polyn)malloc(sizeof(structPolynote));
printf("请输入第%d项的系数与指数:
",i+1);
scanf_s("%f%d",&p->coef,&p->expon);
Insert(p,head);//调用Insert函数插入结点
}
returnhead;
}
主程序的实现:
本实验有四个主程序,分别执行相加,相减,相乘,求导的操作。
显示了用户输入的多项式(降序),及输出的运算结果(降序).
时间复杂度的分析:
Insert函数:
跟节点个数相关
T(n)=0+1+2+…+(n-1)=n^2
Print函数:
跟节点个数有关。
T(n)=n
四、【测试结果(Testing)】(10%)
(本部分应包括:
对实验的测试结果,应具体列出每次测试所输入的数据以及输出的数据,并对测试结果进行分析总结)
多项式加法:
多项式减法:
多项式乘法:
多项式求导:
错误处理:
以减法为例:
分析:
该实验能够自然地显示参与计算的成员和计算结果,有完善的防错系统。
五、【实验总结】(10%)
1.通过实验二,又接触到了之前并未用过的数据结构-链表。
对于链表的操作,自身感觉思考时应该结合图形分析才不易出错,盲目使用指针只能导致未知的错误,甚至影响计算机的正常运行。
2链表指针域是实现链表操作的核心,而指针的初始化和释放又往往是程序的隐患,注意细节才能快速,准确的编程。
3实验二做完后,感觉层次还不清晰,基本操作的定义和抽象数据类型的操作还是没有分开对待,希望在下个实验中有所改进。
六、思考题或【项目运作描述(Operate)】(10%)
线性表的存储可以采用顺序存储结构和链式存储结构两种方式,在解决问题过程中二者有何不同,如何选择?
答:
顺序存储方式适合存储空间大时使用,而且可以进行随机存储,便于查找。
链式存储结构适合在空间零散时使用,不能进行随机存储,但易于删除和添加。
七、【代码】(10%)
(本部分应包括:
完整的代码及充分的注释。
注意纸质的实验报告无需包括此部分。
头文件poly.h部分
#include
#include
//---------------------------建立抽象数据类型复数-------------------
typedefstructPolynote{
floatcoef;
intexpon;
structPolynote*next;
}*Polyn,Polynote;
//-------------------------对复数链表的操作-------------------------
voidInsert(Polynp,Polynh){//插入排序函数
if(p->coef==0)free(p);
else{
Polynq1,q2;
q1=h;q2=h->next;
while(q2&&p->exponexpon){//查找插入位置
q1=q2;
q2=q2->next;
}
if(q2&&p->expon==q2->expon){//将指数相同相合并
q2->coef+=p->coef;
free(p);
if(!
q2->coef){
q1->next=q2->next;
free(q2);
}
}
else{//指数为新时将结点插入
p->next=q2;
q1->next=p;
}
}
}
PolynCreatePolyn(Polynhead,intm){//用于生成结点,并接受数据
inti;//用来计数
Polynp;
p=head=(Polyn)malloc(sizeof(structPolynote));
head->next=NULL;
for(i=0;ip=(Polyn)malloc(sizeof(structPolynote));
printf("请输入第%d项的系数与指数:
",i+1);
scanf_s("%f%d",&p->coef,&p->expon);
Insert(p,head);//调用Insert函数插入结点
}
returnhead;
}
voidPrintPolyn(PolynP){//多项式打印函数
Polynq=P->next;
intflag=1;//用作计数器
if(!
q){
putchar('0');//无输出节点时,输出0
printf("\n");
return;
}
while(q){
if(q->coef>0&&flag!
=1)putchar('+');//q的系数为正且不是第一项,就要输出加号。
if(q->coef!
=1&&q->coef!
=-1){//系数非1或-1的普通情况
printf("%3.1f",q->coef);
if(q->expon)printf("X^%d",q->expon);
}
else{
if(q->coef==1){
if(!
q->expon)putchar('1');//系数为1,指数为0,输出1
elseif(q->expon==1)putchar('X');//系指为1,输出X
elseprintf("X^%d",q->expon);
}
if((int)q->coef==-1){//对复数项的处理
if(!
q->expon)printf("-1");
elseif(q->expon==1)printf("-X");
elseprintf("-X^%d",q->expon);
}
}
q=q->next;
flag++;//保证只有在第一项时,flag值为1.
}
printf("\n");
}
PolynAddPolyn(Polynpa,Polynpb){//多项式加法
Polynqa=pa->next;
Polynqb=pb->next;
Polynheadc,hc,qc;
hc=(Polyn)malloc(sizeof(structPolynote));
hc->next=NULL;
headc=hc;
while(qa||qb){
qc=(Polyn)malloc(sizeof(structPolynote));
switch(compare(qa,qb)){//调用compare函数,确定插入位置。
case1:
{
qc->coef=qa->coef;
qc->expon=qa->expon;
qa=qa->next;
break;
}
case0:
{
qc->coef=qa->coef+qb->coef;
qc->expon=qa->expon;
qa=qa->next;
qb=qb->next;
break;
}
case-1:
{
qc->coef=qb->coef;
qc->expon=qb->expon;
qb=qb->next;
break;
}
}//switch
if(qc->coef!
=0){
qc->next=hc->next;
hc->next=qc;
hc=qc;
}
elsefree(qc);
}//while
returnheadc;
}
PolynDervative(Polynpa){//求导算法
Polynpd,hd;
Polynqa=pa->next;
hd=(Polyn)malloc(sizeof(structPolynote));
hd->next=NULL;
for(;qa;qa=qa->next)
{
pd=(Polyn)malloc(sizeof(structPolynote));
pd->coef=qa->coef*qa->expon;
pd->expon=qa->expon-1;
Insert(pd,hd);
}
returnhd;
}
PolynMinusPolyn(Polynpa,Polynpb){//多项式的减法
Polynqa=pa->next;
Polynqb=pb->next;
Polynheadf,hf,qf;
hf=(Polyn)malloc(sizeof(structPolynote));
hf->next=NULL;
headf=hf;
while(qa||qb){
qf=(Polyn)malloc(sizeof(structPolynote));
switch(compare(qa,qb)){
case1:
{
qf->coef=qa->coef;
qf->expon=qa->expon;
qa=qa->next;
break;
}
case0:
{
qf->coef=qa->coef-qb->coef;
qf->expon=qa->expon;
qa=qa->next;
qb=qb->next;
break;
}
case-1:
{
qf->coef=-(qb->coef);
qf->expon=qb->expon;
qb=qb->next;
break;
}
}//switch
if(qf->coef!
=0){
qf->next=hf->next;
hf->next=qf;
hf=qf;
}
elsefree(qf);
}//while
returnheadf;
}
PolynMultiplyPolyn(Polynpa,Polynpb){//多项式乘法
Polynhf,pf;
Polynqa=pa->next;
Polynqb=pb->next;
hf=(Polyn)malloc(sizeof(structPolynote));
hf->next=NULL;
for(;qa;qa=qa->next){
for(qb=pb->next;qb;qb=qb->next){
pf=(Polyn)malloc(sizeof(structPolynote));
pf->coef=qa->coef*qb->coef;
pf->expon=qa->expon+qb->expon;
Insert(pf,hf);
}
}
returnhf;
}
Main函数部分
1.加法
2.#include"poly.h"
3.intmain(){
4.intm,n,flag=0;//m、n为分别为a、b两个多项式的项数
5.Polynpa=0,pb=0,pc;//定义各式的头指针,pa与pb在使用前付初值NULL
6.printf("请输入第一个多项式a的项数:
");
7.scanf_s("%d",&m);
8.pa=CreatePolyn(pa,m);//建立第一个多项式a
9.printf("请输入第二个多项式b的项数:
");
10.scanf_s("%d",&n);
11.pb=CreatePolyn(pb,n);//建立第二个多项式b
12.printf("**********************************************\n");
13.printf("多项式a:
");PrintPolyn(pa);
14.printf("多项式b:
");PrintPolyn(pb);
15.pc=AddPolyn(pa,pb);
16.printf("多项式a+b:
");PrintPolyn(pc);
17.return0;
18.}
19.减法
#include"poly.h"
intmain(){
intm,n,flag=0;//m、n为分别为a、b两个多项式的项数
Polynpa=0,pb=0,pc;//定义各式的头指针,pa与pb在使用前付初值NULL
printf("请输入第一个多项式的系数:
");
scanf_s("%d",&m);
pa=CreatePolyn(pa,m);//建立第一个多项式a
printf("请输入第二个多项式的系数:
");
scanf_s("%d",&n);
pb=CreatePolyn(pb,n);//建立第二个多项式b
printf("**********************************************\n");
printf("多项式a:
");PrintPolyn(pa);
printf("多项式b:
");PrintPolyn(pb);
pc=MinusPolyn(pa,pb);
printf("多项式a-b:
");PrintPolyn(pc);
return0;
}
乘法
#include"Poly.h"
intmain(){
intm,n,flag=0;//m、n为分别为a、b两个多项式的项数
Polynpa=0,pb=0,pc;//定义各式的头指针,pa与pb在使用前付初值NULL
printf("请输入第一个多项式a的项数:
");
scanf_s("%d",&m);
pa=CreatePolyn(pa,m);//建立第一个多项式a
printf("请输入第二个多项式b的项数:
");
scanf_s("%d",&n);
pb=CreatePolyn(pb,n);//建立第二个多项式b
printf("**********************************************\n");
printf("多项式a:
");PrintPolyn(pa);
printf("多项式b:
");PrintPolyn(pb);
pc=MultiplyPolyn(pa,pb);
printf("多项式a*b:
");PrintPolyn(pc);
return0;
}
求导
20.#include"poly.h"
21.intmain(){
22.intm,n,flag=0;//m、n为分别为a、b两个多项式的项数
23.Polynpa=0,pb=0,pd;
24.printf("请输入一个多项式a的项数:
");
25.scanf_s("%d",&m);
26.pa=CreatePolyn(pa,m);
27.printf("**********************************************\n");
28.printf("多项式a:
");PrintPolyn(pa);
29.pd=Dervative(pa);
30.printf("求导后的多项式a:
");PrintPolyn(pd);
31.return0;
32.}