实验一参考Word下载.docx
《实验一参考Word下载.docx》由会员分享,可在线阅读,更多相关《实验一参考Word下载.docx(29页珍藏版)》请在冰豆网上搜索。
(1)链接存储结构:
此方法中用到的抽象数据类型为结构体:
structnode
{
floatcoef;
intexpo;
structnode*next;
}link;
主程序中给提示建立第一个多项式,并依次调用create函数、order函数和hebing函数,通过调用print函数输出原多项式和整理过后的新多项式。
同理建立并输出第二个多项式,最后通过调用add函数,将两多项式相加,并调用order函数进行整理,最后调用print函数输出结果多项式。
(2)顺序存储结构
structpoly
floatcoef;
intexpo;
}dxs[15],dxs1[15],dxs2[30];
主函数中也会给出提示建立第一个多项式,并依次调用create函数和order函数,通过两次调用print函数输出原多项式和整理过后的新多项式。
之后,将多项式保存,然后同理建立第二个多项式,最后调用add函数,将两多项式相加。
调用print函数输出结果多项式。
因为此方法中我将合并函数加到order函数里,所以没有单一的hebing函数模块。
3.详细设计
(1)链接存储结构
此方法中定义了一个结构体类型:
//定义系数为float类型数据
//定义指数为int类型数据
structnode*next;
structnode*create()//定义建立多项式函数,并返回链表头指针
structnode*h=NULL,*q,*p;
//定义结构体头指针h,标记指针p和q
inti=1,N;
//定义多项式的项数N及标记数i
for(;
i<
=N;
i++)
{p=(structnode*)malloc(sizeof(link));
//为下一个节点分配空间
scanf("
%f"
&
p->
coef);
%d"
expo);
if(i==1){h=p;
q=p;
}
else
{
q->
next=p;
q=p;
}
next=NULL;
p->
returnh;
structnode*order(structnode*h)//定义排序函数,并返回整理后的链表的头指针
structnode*p,*q,*t,*h1,*h2;
//定义三个结构体标记指针和两个头指针
h1=h;
//建立一个新的链表,头指针为h,指向原链表的第一个节点,之后将原链表中的节点一个一个的插入此链表,进行排序
h2=h1->
next;
//将原来的链表建立成待排序链表
h1->
//截断第一个原链表中的节点
while(h2!
=NULL)
q=h1;
p=q->
t=h2;
//从待排序链表中选出一个节点准备插入到新链表中
h2=h2->
//移动待排序链表的头指针,便于进行下一次挑选
t->
if(t->
expo>
q->
expo)//应插入头指针之前的情况
next=q;
h1=t;
continue;
if(p==NULL&
&
t->
expo<
=q->
expo)q->
next=t;
//应插入表尾的情况
while(p!
expo)
break;
q=q->
p=p->
if(p==NULL)q->
returnh1;
//新链表即为按降幂顺序排好的链表,返回其头指针
structnode*hebing(structnode*h)//定义合并函数,并返回合并后的链表的头指针
structnode*p,*q,*r;
//定义三个结构体标记指针
p=h;
q=p->
while(q!
if(p->
expo==q->
coef=p->
coef+q->
coef;
r=q->
free(q);
next=r;
if(r!
q=r->
p=r;
voidprint(structnode*h)//定义输出链表函数
structnode*p;
//定义标记指针,输出链表
coef==0)p=p->
//系数为零时跳过
coef<
0)//系数为负时应加上括号
expo==0)printf("
(%.2f)+"
p->
elseprintf("
(%.2f)*X^%d+"
coef,p->
%.2f+"
%.2f*X^%d+"
printf("
\b\b\n"
);
structnode*add(structnode*h1,structnode*h2)//定义加法函数,并返回结果的链表的头指针
structnode*p,*q,*head,*r;
//定义结构体头指针head和标记指针p,q,r
p=h1;
q=h2;
head=(structnode*)malloc(sizeof(link));
expo){head=h1;
p=p->
expo){head=h2;
q=q->
else{p->
head=p;
r=head;
=NULL&
q!
expo){r->
r->
r=r->
q==NULL)r->
if(p==NULL)r->
if(q==NULL)r->
returnhead;
main()
structnode*h1,*h2,*h3;
//定义三个结构体头指针标记多项式
h1=create();
h1=order(h1);
h1=hebing(h1);
print(h1);
h2=create();
h2=order(h2);
h2=hebing(h2);
print(h2);
h3=add(h1,h2);
h3=hebing(h3);
print(h3);
此方法中也定义一个结构体类型:
voidcreate(intn)//定义建立结构体数组函数
inti;
//定义数组中的循环标记数据i
for(i=0;
n;
dxs[i].coef);
dxs[i].expo);
voidprint(intn)//定义结构体数组输出函数
if(dxs[i].coef<
0)
if(dxs[i].expo==0)printf("
dxs[i].coef);
dxs[i].coef,dxs[i].expo);
elseif(dxs[i].coef>
voidorder(intn)//定义排序函数
inti,temp1,j;
//定义数组中的循环标记数据i与j,和整型标记temp1
floattemp2;
//定义单精度型标记temp2
n-1;
for(j=i+1;
j<
j++)
if(dxs[j].expo>
dxs[i].expo)
temp1=dxs[j].expo;
dxs[j].expo=dxs[i].expo;
dxs[i].expo=temp1;
temp2=dxs[j].coef;
dxs[j].coef=dxs[i].coef;
dxs[i].coef=temp2;
if(dxs[i].expo==dxs[i+1].expo)
dxs[i+1].coef=dxs[i].coef+dxs[i+1].coef;
if(i==n-2)
dxs[i].coef=dxs[i+1].coef;
dxs[i+1].coef=0;
for(j=i;
dxs[j].coef=dxs[j+1].coef;
dxs[j].expo=dxs[j+1].expo;
dxs[j].coef=0;
i--;
voidadd(intn1,intn2)//定义加法函数
inti=0,j=0,p,m;
//定义数组中的循环标记数据i,j,p,m
for(p=0;
;
p++)
if(dxs[i].expo==dxs1[j].expo)
dxs2[p].coef=dxs[i].coef+dxs1[j].coef;
dxs2[p].expo=dxs[i].expo;
i++;
j++;
if(dxs[i].expo>
dxs1[j].expo)
dxs2[p].coef=dxs[i].coef;
dxs2[p].coef=dxs1[j].coef;
dxs2[p].expo=dxs1[j].expo;
if(i==n1||j==n2)
p++;
if(i==n1)
n2;
n1;
for(m=0;
m<
p;
m++)
if(dxs2[m].coef<
if(dxs2[m].expo==0)printf("
dxs2[m].coef);
dxs2[m].coef,dxs2[m].expo);
elseif(dxs2[m].coef>
intn1,n2,i;
//定义多项式的项数n1与n2,和循环标记数据i
n1);
create(n1);
order(n1);
print(n1);
i++){
dxs1[i].coef=dxs[i].coef;
dxs1[i].expo=dxs[i].expo;
n2);
create(n2);
order(n2);
print(n2);
add(n1,n2);
4.调试分析
在此方法的实现过程中,没有比较大的麻烦,因为最近一直在用链表进行编程,已经比较熟悉了链表的基本操作,只是在一些实现方便与否、接近真实情况与否进行了一番思考。
首先,我因为做题的习惯,所以没有考虑到假如输入多项式时可以打乱顺序输入,即不按照降幂或升幂的形式进行输入。
意识到可能有此情况后,我就添加了一个order函数,对输入的原多项式进行排序,解决掉因打乱顺序输入而导致程序出错的可能性。
之后,又有人提出,假如多项式中有指数相同的项,那如果没有合并一类作用的函数做整理的话,也会出错。
因此,我又着手编一个合并函数。
合并函数其实不难,只要把原多项式进行排序后就变得很简单了。
只需要将指数相同的项的系数进行加法运算,之后删去后一个节点即可。
最后,还有一个输出形式的问题。
因为假如系数是负数的时候,需要将其用括号括起来,这也是数学运算中的规定。
因此,我又对输出函数:
print函数进行了一些修改,并且在修改过程中又发现,假如指数为零时,输出的应该是只有系数,所以我又顺便将这方面的漏洞加以补充。
当然,我这个程序毕竟还是有不足之处的。
一、没有利用到链表的一项基本操作:
删除节点。
在输出过程中,我对系数为零的节点的处理方式是跳过,而不是删除,虽然不会影响到最终的输出结果,但对内存其实是有一些浪费,毕竟程序需要的不仅是结果正确,而且还要做到时间和空间上的节约。
二、当一项的指数为1时,应当输出的是X,而不是X^1,所以此方面仍需要改进。
虽然此项改进不是很难,但由于时间紧迫,没有来得及修改,但我会在以后的空闲时间内将其完善。
在算法的时空复杂度上,我没有进行过多的考虑,因为现在自己的水平还没有那么高,我只知道,在排序函数中,我用的冒泡排序方法是一种效率很低的方法,时间复杂度为O(n2)。
而同学向我推荐过的一种插入排序方法,一种部分有序的排序方法,算下来时间复杂度为O(n2-n),因此自己还需要将此程序加以改进。
在此方法的实现过程中,我确实费了很大的时间。
因为数组很长时间没有用到过了,很多基本操作又比链表复杂,因此,我花了相当长的时间才将此程序完成。
定义结构体数组方面虽然很简单,但用起来就会变的相当复杂,并且由于自己的数组方面的知识不是很牢靠,因此,语法错误很多,调试费了很长的时间,并且很多次无法通过编译。
最终在同学的帮助下,自己又花了大量的时间,终于将程序编出。
因为程序需要的作用函数已在链表方法中掌握,所以此项内容里我没有进行更多的考虑,只是感觉用结构体数组实现的时候,将排序函数和合并函数写在一起会更加方便,所以此方法中我只设置了一个排序函数,并且在做加法的函数中附带了输出作用,因此不再调用print函数输出数组。
但此相加的函数似乎有点问题,在多项式比较复杂的时候,输出总是有点问题。
自己研究了很长时间之后还是找不出问题,希望老师能发现并指出,完善此程序。
通过编此程序,我感觉到自己在数组的知识点上掌握的不够扎实,以后还需多加练习,熟练掌握数组的基本操作方法。
5.用户使用说明
运行程序后,会出现提示:
请输入第一个多项式
请输入多项式的项数:
(这时应输入其项数(整型数据),后按回车键;
比如输入:
2)
请输入第1项的系数:
请输入第1项的指数:
(比如依次输入2,2)
请输入第2项的系数:
请输入第2项的指数:
(比如依次输入3,3)
输入的第一个多项式为:
2.00*X^2+3.00*X^3
按降幂排列后多项式为:
3.00*X^3+2.00*X^2
请输入第二个多项式;
(比如输入:
(比如依次输入1,1)
1.00*X^1+2.00*X^2
2.00*X^2+1.00*X^1
相加后的多项式为:
3.00*X^3+4.00*X^2+1.00*X^1
请输入第一个多项式的项数:
您输入的第一个多项式为:
降幂排序后该多项式变为:
请输入第二个多项式的项数:
两个多项式相加后的结果为:
6.测试结果
7.附录
#include"
stdio.h"
stdlib.h"
"
N);
请输入第%d项的系数:
i);
fflush(stdin);
请输入第%d项的指数:
}//建立头节点