一元多项式的运算.docx
《一元多项式的运算.docx》由会员分享,可在线阅读,更多相关《一元多项式的运算.docx(22页珍藏版)》请在冰豆网上搜索。
一元多项式的运算
数据结构课程设计
实验报
专业班级:
学号:
姓名:
2011年1月1日
题目:
1、题目描述
一元多项式的运算在此题中实现加、减法的运算,而多项式的减法可以通过加法来实现(只需在减法运算时系数前加负号)。
在数学上,一个一元n次多项式Pn(X)可按降序写成:
Pn(X)=PnX^n+P(n-1)X^(n-1)++P1X+P0
它由n+1个系数惟一确定,因此,在计算机里它可以用一个线性表P来表示:
P=(Pn,P(n-1),,P1,P0)
每一项的指数i隐含在其系数Pi的序号里。
假设Qm(X)是一元m次多项式,同样可以用一个线性表Q来表示:
Q=(qm,q(m-1),,q1,q0)
不是一般性,假设吗吗mRn(X)=Pn(X)+Qm(X)很显然,可以对P,Q和R采用顺序存储结构,使得多项式相加的算法定义和实现简单化。然而,在通常的应用中,多项式的次数可能变化很大而且很高,使得顺序存储结构的最大长度很难确定。特别是在处理项数少且次数特别高的情况下,对内存空间的浪费是相当大的。因此,一般情况下,都采用链式存储结构来处理多项式的运算,使得两个线性链表分别表示一元多项式Pn(X)和Qm(X),每个结点表示多项式中的一项。通过分析多项式的特征,不难看出多项式是由单项式构成的,而每个单项式都具有系数和指数,当系数为0时,该项就是去了意义,在计算机内要表示一个多项式,至少具有以下数据信息:系数信息、指数信息和指向下一个单项式的指针。通过指针,我们就可以把多个单项式连接起来,形成一个多项式。2、任务要求系数定义的是float型,范围是3.4*10^-38~3.4*10^38;指数定义的是int型,范围是-2147483648~+2147483647;输入多项式系数及指数,系统会自动将系数转化为浮点型。功能:(1).提示输入数据。要求先输入多项式的项数。(2).创建多项式。接收输入的数据,并保存到链表中。(3).显示已经创建好的多项式。(4).实现加、减法运算。(5).退出程序3、概要设计(1)链表结点的类型定义(2)建立有序链表voidCreatPolyn(LinkList&L,intn)(3)多项式链表的相加voidAddPolyn(LinkListLa,LinkListLb,LinkList&Lc)(4)多项式链表的输出voidprintList(LinkListL)4、详细设计(1)链表结点的类型定义typedefstruct//在struct前使用关键字typedef,表示是声明新类型{floatcoef;//系数intexpn;//指数typedefstructnode//单链表的存储{DataTypedata;//数据域structnode*next;//指向下一个结点}ListNode,*LinkList;//ListNode是结点的新类型,LinkList是指向ListNode类型的结点的指针类型(2)建立有序链表要实现多项式的加法运算,首先要建立多项式的存储结构,每一个一元多项式的存储结构就是一个有序单链表。有序链表的基本操作定义与线性链表有两处不同,一个是结点的查找定位操作LocateNode有所不同,二是结点的插入操作InsertNode不同,这两个操作算法分别如下://结点的查找定位intLocateNode(LinkListL,DataTypee,int&q){ListNode*p=L->next;q=0;//记录结点位置序号while(p&&e.expndata.expn){p=p->next;q++;}if(p==NULL||e.expn!=p->data.expn)return0;elsereturn1;}voidInsertNode(LinkList&L,DataTypee,intq)函数功能:将新的节点p插入到现有链表的后面,并确保多项式的指数expn是升序。将s节点插入到e所指向的链表。在该函数的操作中,要注意指针是如何移动的。//有序链表结点的插入voidInsertNode(LinkList&L,DataTypee,intq){ListNode*s,*p;inti=0;p=L;while(p->next&&i{p=p->next;i++;}//查找插入位置s=(ListNode*)malloc(sizeof(ListNode));s->data.coef=e.coef;s->data.expn=e.expn;s->next=p->next;p->next=s;}有了上述两个“结点的查找定位算法”和“有序链表结点的插入算法”,intn保存的多项式的项数,使用for语句,控制输入多项式的每一项。当创建的链表长度为n时,将不再提示用户继续输入多项式的系数和指数。建立一个一元多项式的单链表的具体算法如下://多项式链表的建立voidCreatPolyn(LinkList&L,intn){LinkListpa;//定义一个头指针为pa链表inti,q;//i用来计输入的项数,q指结点的位置序号DataTypee;//插入的值epa=(ListNode*)malloc(sizeof(ListNode));//生成链表头结点pa->next=NULL;for(i=1;i<=n;i++){scanf("%f,%d",&e.coef,&e.expn);if(!LocateNode(pa,e,q))//当前链表中不存在该指数项InsertNode(pa,e,q);//调用InsertNode函数插入结点}L=pa;(3)多项式链表的相加根据一元多项式相加的运算规则:对于一元多项式中所有指数相同的项,对应系数相加,若其和不为零,则构成“和多项式”中的一项;对于两个一元多项式中所有指数不相同的项,则分别复制到“和多项式”中相应的位置。根据以上运算规则,其实现算法思路如下:假设pc为指向“和多项式链表”当前尾结点的指针,指针pa和pb分别指向两个多项式中当前进行比较的某个结点,则比较两个结点中的指数项值,有下面三种情况:1.若指针pa所指结点的指数值大于指针pb所指结点的指数值,则取pa指针所指向的结点插入到pc指针所指结点之后,分别修改指针pa和pc,使之指向链表的下一个结点;2.若指针pa所指结点的指数值小于指针pb所指结点的指数值,则取pb指针所指向的结点插入到pc指针所指结点之后,分别修改指针pb和pc,使之指向链表的下一个结点;3.若指针pa所指结点的指数值等于指针pb所指结点的指数值,则将两结点中的系数相加,如果其和数不为零,则修改pa指针所指结点中的系数值,将其结点插入到pc指针所指结点之后,分别修改pa、pb和pc,使之指向各自链表的下一个结点,同时删除并释放指针pb原先指向各自链表的下一个结点;如果和数为零,保存pa和pb所指向的结点,修改pa和pb指针使之指向各自链表的下一个结点,然后释放保存的两个结点。再比较指针pa和pb指向节点中的指数项值,分3种情况进行处理⋯..这样的操作一直继续到pa或pb等于NULL为止。最后将未结束的链表后面剩余的节点连接到pc指针所指向结点之后。上述多项式的相加过程和两个有序链表合并的过程类似,不同之处仅在于多项式的比较多了相等比较后的操作。因此,多项式相加的过程完全可以利用线性链表的基本操作来实现。具体实现多项式相加的算法如下://多项式链表的相加voidAddPolyn(LinkListLa,LinkListLb,LinkList&Lc){//两个有序链表La和Lb表示的多项式相加ListNode*pa,*pb,*pc,*s;floatsum;pa=La->next;pb=Lb->next;//pa和pb分别指向两个链表的开始结点Lc=pc=La;//用La的头结点作为Lc的头结点while(pa&&pb){if(pa->data.expn>pb->data.expn){pc->next=pa;pc=pa;pa=pa->next;}elseif(pa->data.expndata.expn){pc->next=pb;pc=pb;pb=pb->next;}else{sum=pa->data.coef+pb->data.coef;if(fabs(sum)>0){//系数和不为零pa->data.coef=sum;pc->next=pa;pc=pa;pa=pa->next;s=pb;pb=pb->next;free(s);}else{s=pa;pa=pa->next;free(s);s=pb;pb=pb->next;free(s);}}}pc->next=pa?pa:pb;//插入链表剩余部分free(Lb);//释放Lb的头结点}(4)多项式链表的输出voidprintList(LinkListL)函数功能:显示多项式链表。在输出项中使用了条件表达式,当系数项为正数时,在系数前输出一个“+”号,否则输出一个空格,而负数的负号还照常输出,使得输出结果尽量与原多项式的表示形式类似。因此,输出多项式链表的算法实现如下://多项式链表的输出voidprintList(LinkListL){p=L->next;while(p){printf("%c%fx^%d",(p->data.coef>0?'+':''),p->data.coef,p->data.expn);p=p->next;}printf("\n");}源程序代码:#include#include#include//多项式链表结点类型定义typedefstruct//在struct前使用关键字typedef,表示是声明新类型{floatcoef;//系数intexpn;//指数}DataType;//DataType是新类型typedefstructnode//单链表的存储{DataTypedata;//数据域structnode*next;//指向下一个结点}ListNode,*LinkList;//ListNode是结点的新类型,LinkList是指向ListNode类型的结点的指针类型//结点的查找定位intLocateNode(LinkListL,DataTypee,int&q){ListNode*p=L->next;q=0;//记录结点位置序号while(p&&e.expndata.expn){p=p->next;q++;}if(p==NULL||e.expn!=p->data.expn)return0;elsereturn1;}//有序链表结点的插入voidInsertNode(LinkList&L,DataTypee,intq){inti=0;p=L;while(p->next&&i{p=p->next;i++;}s=(ListNode*)malloc(sizeof(ListNode));s->data.coef=e.coef;s->data.expn=e.expn;s->next=p->next;p->next=s;}//多项式链表的建立voidCreatPolyn(LinkList&L,intn){LinkListpa;//定义一个头指针为pa链表inti,q;//i用来计输入的项数,q指结点的位置序号DataTypee;//插入的值epa=(ListNode*)malloc(sizeof(ListNode));//生成链表头结点pa->next=NULL;scanf("%f,%d",&e.coef,&e.expn);if(!LocateNode(pa,e,q))//当前链表中不存在该指数项InsertNode(pa,e,q);//调用InsertNode函数插入结点}L=pa;}//多项式链表的输出voidprintList(LinkListL){ListNode*p;p=L->next;while(p){printf("%c%fx^%d",(p->data.coef>0?'+':''),p->data.coef,p->data.expn);p=p->next;}printf("\n");}//多项式链表的相加voidAddPolyn(LinkListLa,LinkListLb,LinkList&Lc){//两个有序链表La和Lb表示的多项式相加floatsum;pa=La->next;pb=Lb->next;//pa和pb分别指向两个链表的开始结点Lc=pc=La;//用La的头结点作为Lc的头结点while(pa&&pb){if(pa->data.expn>pb->data.expn){pc->next=pa;pc=pa;pa=pa->next;}elseif(pa->data.expndata.expn){pc->next=pb;pc=pb;pb=pb->next;}else{sum=pa->data.coef+pb->data.coef;if(fabs(sum)>0){//系数和不为零pa->data.coef=sum;pc->next=pa;pc=pa;pa=pa->next;s=pb;pb=pb->next;free(s);}else{s=pa;pa=pa->next;free(s);s=pb;pb=pb->next;free(s);}}}pc->next=pa?pa:pb;//插入链表剩余部分free(Lb);//释放Lb的头结点}//主控函数voidmain(){LinkListLa,Lb,Lc;intn;printf("输入第一个多项式的项数:");scanf("%d",&n);指数:\n");指数:");printf("输入第一个多项式的每一项的系数CreatPolyn(La,n);printf("第一个多项式为:");printList(La);printf("输入第二个多项式的项数:");scanf("%d",&n);printf("输入第二个多项式的每一项的系数CreatPolyn(Lb,n);printf("第二个多项式为:");printList(Lb);AddPolyn(La,Lb,Lc);printf("\n相加后的和多项式为:");printList(Lc);}5、调试分析此一元多项式的运算程序,只能实现一元多项式的加、减法,不能实现一元多项式的乘法,而且若想计数多个多项式的和或者差的话,必须退出界面重新开始计算。在补充程序里面,解决了程序没有的选择功能表的功能,及其多项式的乘法运算。6.测试结果输入多项式的项数,并且显示多项式及其两个多项式的和:补充程序:多项式运算程序具有以下基本功能:1.界面输出,提示如何输入数据。要求先输入多项式的项数。2.创建多项式。接收输入的数据,并保存到链表中。3.显示程序的功能表,允许使用者选择运算类型。4.显示已经创建好的多项式。5.实现加法运算。6.实现减法运算。7.实现乘法运算。8.清除内存内容,销毁创建的链表,退出程序。该程序实现了多项式的创建、多项式的加法、减法、乘法运算以及多项式的清除。源程序代码:#include#include********************//*该函数的功能:在计算机内要表示一个多项式,至少以下数据信息--系数信息、指数信息和指向下一个单项式的指针。通过指针,我们就可以把多个单项式连接起来,形式一个多项式.*/typedefstructPolynomial{floatcoef;//系数intexpn;//指数structPolynomial*next;//指向下一个结点}*Polyn,Polynomial;//Polyn为结点指针类型/**************以下函数用来实现链表的顺序排列和合并相同的项***************//*该函数的功能:实现链表的顺序排列和合并相同的项。将新的节点p插入到现有链表的后面,并确保多项式的指数expn是升序。将p节点插入到head所指向的链表。在该函数的操作中,要注意指针是如何移动的。*/voidInsert(Polynp,Polynh){if(p->coef==0)free(p);//系数为0的话释放结点else//如果系数不为0{q1=h;q2=h->next;{q1=q2;q2=q2->next;}if(q2&&p->expn==q2->expn)//将指数相同相合并{q2->coef+=p->coef;free(p);if(!q2->coef)//系数为0的话释放结点{q1->next=q2->next;free(q2);}}else//指数为新时将结点插入{p->next=q2;q1->next=p;}}}//Insert以下函数实现建立一个多项式/*该函数功能:创建新的多项式链表。intm保存的多项式的项数,使用for语句,控制输入多项式的每一项。当创建的链表长度为m时,将不再提示用户继续输入多项式的系数和指数。*/PolynCreatePolyn(Polynhead,intm)//建立一个头指针为head、项数为m的一元多项式,intm是保存的多项式的项数{//在主程序初始时,先输入的多项式中的项数m、n在这里为m。主程序中的pa、pb在此为headinti;//定义inti计数,当i当i=m时,输入完毕,该链表也创建完毕。Polynp;//定义一个p链表p=head=(Polyn)malloc(sizeof(structPolynomial));head->next=NULL;for(i=0;i当创建的链表长度为m时,将不再提示用户继续输入多项式的系数和指数。{p=(Polyn)malloc(sizeof(structPolynomial));//建立新结点以接收数据,用到分配空间的函数malloc()为新建链表分配空间printf("请输入第%d项的系数与指数:",i+1);scanf("%f%d",&p->coef,&p->expn);Insert(p,head);//调用Insert函数插入结点}returnhead;}//CreatePolyn以下函数实现多项式的销毁/*该函数的功能:销毁掉创建的两个链表,释放内存。以辅助退出程序*/voidDestroyPolyn(Polynp)//销毁多项式p{Polynq1,q2;q1=p->next;q2=q1->next;while(q1->next){free(q1);q1=q2;//指针后移q2=q2->next;}}以下函数实现显示输出多项式*******************/尤其是第/*该函数的功能:显示多项式链表。在该函数中较复杂的是如何控制链表的输出项的输出,同时还有符号的控制。在输出第一项时要判断是不是常数项,若是,则不要输出字符x。*/voidPrintPolyn(PolynP){Polynq=P->next;intflag=1;//项数计数器,flag=1表示为第一项if(!q)//若多项式为空,输出0{putchar('0');printf("\n");return;}while(q){if(q->coef>0&&flag!=1)//系数大于0且不是第一项putchar('+');if(q->coef!=1&&q->coef!=-1)//系数非1或-1的普通情况{printf("%g",q->coef);if(q->expn==1)putchar('X');elseif(q->expn)printf("X^%d",q->expn);else{if(q->coef==1){if(!q->expn)putchar('1');elseif(q->expn==1)putchar('X');elseprintf("X^%d",q->expn);}if(q->coef==-1){if(!q->expn)printf("-1");elseif(q->expn==1)printf("-X");elseprintf("-X^%d",q->expn);}}q=q->next;flag++;}//whileprintf("\n");}//PrintPolyn0
Rn(X)=Pn(X)+Qm(X)
很显然,可以对P,Q和R采用顺序存储结构,使得多项式相加的算法定义和实现简单化。
然而,在通常的应用中,多项式的次数可能变化很大而且很高,使得顺序存储结构的最大长度很难确定。
特别是在处理项数少且次数特别高的情况下,对内存空间的浪费是相当大的。
因此,一般情况下,都采用链式存储结构来处理多项式的运算,使得两个线性链表分别表示一元多项式Pn(X)和Qm(X),每个结点表示多项式中的一项。
通过分析多项式的特征,不难看出多项式是由单项式构成的,而每个单项式都具有系数和指数,当系数为0时,该项就是去了意义,在计算机内要表示一个多项式,至少具有以下数据信息:
系数信息、指数信息和指向下一个单项式的指针。
通过指针,我们就可以把多个单项式连接起来,形成一个多项式。
2、任务要求
系数定义的是float型,范围是3.4*10^-38~3.4*10^38;指数定义的是int型,范围是-2147483648~+2147483647;输入多项式系数及指数,系统会自动将系数转化为浮点
型。
功能:
(1).提示输入数据。
要求先输入多项式的项数。
(2).创建多项式。
接收输入的数据,并保存到链表中。
(3).显示已经创建好的多项式。
(4).实现加、减法运算。
(5).退出程序
3、概要设计
(1)链表结点的类型定义
(2)建立有序链表voidCreatPolyn(LinkList&L,intn)
(3)多项式链表的相加voidAddPolyn(LinkListLa,LinkListLb,LinkList&Lc)
(4)多项式链表的输出voidprintList(LinkListL)
4、详细设计
typedefstruct//在struct前使用关键字typedef,表示是声明新类型
{
floatcoef;//系数
intexpn;//指数
typedefstructnode
//单链表的存储
DataTypedata;
//数据域
structnode*next;
//指向下一个结点
}ListNode,*LinkList;
//ListNode是结点的新类型,LinkList是指向ListNode类型
的结点的指针类型
(2)建立有序链表
要实现多项式的加法运算,首先要建立多项式的存储结构,每一个一元多项式的存
储结构就是一个有序单链表。
有序链表的基本操作定义与线性链表有两处不同,一个是结点
的查找定位操作LocateNode
有所不同,二是结点的插入操作InsertNode不同,这两个
操作算法分别如下:
//结点的查找定位
intLocateNode(LinkListL,DataTypee,int&q)
ListNode*p=L->next;
q=0;//记录结点位置序号
while(p&&e.expndata.expn)
p=p->next;
q++;
}
if(p==NULL||e.expn!
=p->data.expn)
return0;
else
return1;
voidInsertNode(LinkList&L,DataTypee,intq)函数功能:
将新的节点p插入到现
有链表的后面,并确保多项式的指数expn是升序。
将s节点插入到e所指向的链表。
在该函数的操作中,要注意指针是如何移动的。
//有序链表结点的插入
voidInsertNode(LinkList&L,DataTypee,intq)
ListNode*s,*p;
inti=0;
p=L;
while(p->next&&i{p=p->next;i++;}//查找插入位置s=(ListNode*)malloc(sizeof(ListNode));s->data.coef=e.coef;s->data.expn=e.expn;s->next=p->next;p->next=s;}有了上述两个“结点的查找定位算法”和“有序链表结点的插入算法”,intn保存的多项式的项数,使用for语句,控制输入多项式的每一项。当创建的链表长度为n时,将不再提示用户继续输入多项式的系数和指数。建立一个一元多项式的单链表的具体算法如下://多项式链表的建立voidCreatPolyn(LinkList&L,intn){LinkListpa;//定义一个头指针为pa链表inti,q;//i用来计输入的项数,q指结点的位置序号DataTypee;//插入的值epa=(ListNode*)malloc(sizeof(ListNode));//生成链表头结点pa->next=NULL;for(i=1;i<=n;i++){scanf("%f,%d",&e.coef,&e.expn);if(!LocateNode(pa,e,q))//当前链表中不存在该指数项InsertNode(pa,e,q);//调用InsertNode函数插入结点}L=pa;(3)多项式链表的相加根据一元多项式相加的运算规则:对于一元多项式中所有指数相同的项,对应系数相加,若其和不为零,则构成“和多项式”中的一项;对于两个一元多项式中所有指数不相同的项,则分别复制到“和多项式”中相应的位置。根据以上运算规则,其实现算法思路如下:假设pc为指向“和多项式链表”当前尾结点的指针,指针pa和pb分别指向两个多项式中当前进行比较的某个结点,则比较两个结点中的指数项值,有下面三种情况:1.若指针pa所指结点的指数值大于指针pb所指结点的指数值,则取pa指针所指向的结点插入到pc指针所指结点之后,分别修改指针pa和pc,使之指向链表的下一个结点;2.若指针pa所指结点的指数值小于指针pb所指结点的指数值,则取pb指针所指向的结点插入到pc指针所指结点之后,分别修改指针pb和pc,使之指向链表的下一个结点;3.若指针pa所指结点的指数值等于指针pb所指结点的指数值,则将两结点中的系数相加,如果其和数不为零,则修改pa指针所指结点中的系数值,将其结点插入到pc指针所指结点之后,分别修改pa、pb和pc,使之指向各自链表的下一个结点,同时删除并释放指针pb原先指向各自链表的下一个结点;如果和数为零,保存pa和pb所指向的结点,修改pa和pb指针使之指向各自链表的下一个结点,然后释放保存的两个结点。再比较指针pa和pb指向节点中的指数项值,分3种情况进行处理⋯..这样的操作一直继续到pa或pb等于NULL为止。最后将未结束的链表后面剩余的节点连接到pc指针所指向结点之后。上述多项式的相加过程和两个有序链表合并的过程类似,不同之处仅在于多项式的比较多了相等比较后的操作。因此,多项式相加的过程完全可以利用线性链表的基本操作来实现。具体实现多项式相加的算法如下://多项式链表的相加voidAddPolyn(LinkListLa,LinkListLb,LinkList&Lc){//两个有序链表La和Lb表示的多项式相加ListNode*pa,*pb,*pc,*s;floatsum;pa=La->next;pb=Lb->next;//pa和pb分别指向两个链表的开始结点Lc=pc=La;//用La的头结点作为Lc的头结点while(pa&&pb){if(pa->data.expn>pb->data.expn){pc->next=pa;pc=pa;pa=pa->next;}elseif(pa->data.expndata.expn){pc->next=pb;pc=pb;pb=pb->next;}else{sum=pa->data.coef+pb->data.coef;if(fabs(sum)>0){//系数和不为零pa->data.coef=sum;pc->next=pa;pc=pa;pa=pa->next;s=pb;pb=pb->next;free(s);}else{s=pa;pa=pa->next;free(s);s=pb;pb=pb->next;free(s);}}}pc->next=pa?pa:pb;//插入链表剩余部分free(Lb);//释放Lb的头结点}(4)多项式链表的输出voidprintList(LinkListL)函数功能:显示多项式链表。在输出项中使用了条件表达式,当系数项为正数时,在系数前输出一个“+”号,否则输出一个空格,而负数的负号还照常输出,使得输出结果尽量与原多项式的表示形式类似。因此,输出多项式链表的算法实现如下://多项式链表的输出voidprintList(LinkListL){p=L->next;while(p){printf("%c%fx^%d",(p->data.coef>0?'+':''),p->data.coef,p->data.expn);p=p->next;}printf("\n");}源程序代码:#include#include#include//多项式链表结点类型定义typedefstruct//在struct前使用关键字typedef,表示是声明新类型{floatcoef;//系数intexpn;//指数}DataType;//DataType是新类型typedefstructnode//单链表的存储{DataTypedata;//数据域structnode*next;//指向下一个结点}ListNode,*LinkList;//ListNode是结点的新类型,LinkList是指向ListNode类型的结点的指针类型//结点的查找定位intLocateNode(LinkListL,DataTypee,int&q){ListNode*p=L->next;q=0;//记录结点位置序号while(p&&e.expndata.expn){p=p->next;q++;}if(p==NULL||e.expn!=p->data.expn)return0;elsereturn1;}//有序链表结点的插入voidInsertNode(LinkList&L,DataTypee,intq){inti=0;p=L;while(p->next&&i{p=p->next;i++;}s=(ListNode*)malloc(sizeof(ListNode));s->data.coef=e.coef;s->data.expn=e.expn;s->next=p->next;p->next=s;}//多项式链表的建立voidCreatPolyn(LinkList&L,intn){LinkListpa;//定义一个头指针为pa链表inti,q;//i用来计输入的项数,q指结点的位置序号DataTypee;//插入的值epa=(ListNode*)malloc(sizeof(ListNode));//生成链表头结点pa->next=NULL;scanf("%f,%d",&e.coef,&e.expn);if(!LocateNode(pa,e,q))//当前链表中不存在该指数项InsertNode(pa,e,q);//调用InsertNode函数插入结点}L=pa;}//多项式链表的输出voidprintList(LinkListL){ListNode*p;p=L->next;while(p){printf("%c%fx^%d",(p->data.coef>0?'+':''),p->data.coef,p->data.expn);p=p->next;}printf("\n");}//多项式链表的相加voidAddPolyn(LinkListLa,LinkListLb,LinkList&Lc){//两个有序链表La和Lb表示的多项式相加floatsum;pa=La->next;pb=Lb->next;//pa和pb分别指向两个链表的开始结点Lc=pc=La;//用La的头结点作为Lc的头结点while(pa&&pb){if(pa->data.expn>pb->data.expn){pc->next=pa;pc=pa;pa=pa->next;}elseif(pa->data.expndata.expn){pc->next=pb;pc=pb;pb=pb->next;}else{sum=pa->data.coef+pb->data.coef;if(fabs(sum)>0){//系数和不为零pa->data.coef=sum;pc->next=pa;pc=pa;pa=pa->next;s=pb;pb=pb->next;free(s);}else{s=pa;pa=pa->next;free(s);s=pb;pb=pb->next;free(s);}}}pc->next=pa?pa:pb;//插入链表剩余部分free(Lb);//释放Lb的头结点}//主控函数voidmain(){LinkListLa,Lb,Lc;intn;printf("输入第一个多项式的项数:");scanf("%d",&n);指数:\n");指数:");printf("输入第一个多项式的每一项的系数CreatPolyn(La,n);printf("第一个多项式为:");printList(La);printf("输入第二个多项式的项数:");scanf("%d",&n);printf("输入第二个多项式的每一项的系数CreatPolyn(Lb,n);printf("第二个多项式为:");printList(Lb);AddPolyn(La,Lb,Lc);printf("\n相加后的和多项式为:");printList(Lc);}5、调试分析此一元多项式的运算程序,只能实现一元多项式的加、减法,不能实现一元多项式的乘法,而且若想计数多个多项式的和或者差的话,必须退出界面重新开始计算。在补充程序里面,解决了程序没有的选择功能表的功能,及其多项式的乘法运算。6.测试结果输入多项式的项数,并且显示多项式及其两个多项式的和:补充程序:多项式运算程序具有以下基本功能:1.界面输出,提示如何输入数据。要求先输入多项式的项数。2.创建多项式。接收输入的数据,并保存到链表中。3.显示程序的功能表,允许使用者选择运算类型。4.显示已经创建好的多项式。5.实现加法运算。6.实现减法运算。7.实现乘法运算。8.清除内存内容,销毁创建的链表,退出程序。该程序实现了多项式的创建、多项式的加法、减法、乘法运算以及多项式的清除。源程序代码:#include#include********************//*该函数的功能:在计算机内要表示一个多项式,至少以下数据信息--系数信息、指数信息和指向下一个单项式的指针。通过指针,我们就可以把多个单项式连接起来,形式一个多项式.*/typedefstructPolynomial{floatcoef;//系数intexpn;//指数structPolynomial*next;//指向下一个结点}*Polyn,Polynomial;//Polyn为结点指针类型/**************以下函数用来实现链表的顺序排列和合并相同的项***************//*该函数的功能:实现链表的顺序排列和合并相同的项。将新的节点p插入到现有链表的后面,并确保多项式的指数expn是升序。将p节点插入到head所指向的链表。在该函数的操作中,要注意指针是如何移动的。*/voidInsert(Polynp,Polynh){if(p->coef==0)free(p);//系数为0的话释放结点else//如果系数不为0{q1=h;q2=h->next;{q1=q2;q2=q2->next;}if(q2&&p->expn==q2->expn)//将指数相同相合并{q2->coef+=p->coef;free(p);if(!q2->coef)//系数为0的话释放结点{q1->next=q2->next;free(q2);}}else//指数为新时将结点插入{p->next=q2;q1->next=p;}}}//Insert以下函数实现建立一个多项式/*该函数功能:创建新的多项式链表。intm保存的多项式的项数,使用for语句,控制输入多项式的每一项。当创建的链表长度为m时,将不再提示用户继续输入多项式的系数和指数。*/PolynCreatePolyn(Polynhead,intm)//建立一个头指针为head、项数为m的一元多项式,intm是保存的多项式的项数{//在主程序初始时,先输入的多项式中的项数m、n在这里为m。主程序中的pa、pb在此为headinti;//定义inti计数,当i当i=m时,输入完毕,该链表也创建完毕。Polynp;//定义一个p链表p=head=(Polyn)malloc(sizeof(structPolynomial));head->next=NULL;for(i=0;i当创建的链表长度为m时,将不再提示用户继续输入多项式的系数和指数。{p=(Polyn)malloc(sizeof(structPolynomial));//建立新结点以接收数据,用到分配空间的函数malloc()为新建链表分配空间printf("请输入第%d项的系数与指数:",i+1);scanf("%f%d",&p->coef,&p->expn);Insert(p,head);//调用Insert函数插入结点}returnhead;}//CreatePolyn以下函数实现多项式的销毁/*该函数的功能:销毁掉创建的两个链表,释放内存。以辅助退出程序*/voidDestroyPolyn(Polynp)//销毁多项式p{Polynq1,q2;q1=p->next;q2=q1->next;while(q1->next){free(q1);q1=q2;//指针后移q2=q2->next;}}以下函数实现显示输出多项式*******************/尤其是第/*该函数的功能:显示多项式链表。在该函数中较复杂的是如何控制链表的输出项的输出,同时还有符号的控制。在输出第一项时要判断是不是常数项,若是,则不要输出字符x。*/voidPrintPolyn(PolynP){Polynq=P->next;intflag=1;//项数计数器,flag=1表示为第一项if(!q)//若多项式为空,输出0{putchar('0');printf("\n");return;}while(q){if(q->coef>0&&flag!=1)//系数大于0且不是第一项putchar('+');if(q->coef!=1&&q->coef!=-1)//系数非1或-1的普通情况{printf("%g",q->coef);if(q->expn==1)putchar('X');elseif(q->expn)printf("X^%d",q->expn);else{if(q->coef==1){if(!q->expn)putchar('1');elseif(q->expn==1)putchar('X');elseprintf("X^%d",q->expn);}if(q->coef==-1){if(!q->expn)printf("-1");elseif(q->expn==1)printf("-X");elseprintf("-X^%d",q->expn);}}q=q->next;flag++;}//whileprintf("\n");}//PrintPolyn0
{p=p->next;i++;}//查找插入位置s=(ListNode*)malloc(sizeof(ListNode));s->data.coef=e.coef;s->data.expn=e.expn;s->next=p->next;p->next=s;}有了上述两个“结点的查找定位算法”和“有序链表结点的插入算法”,intn保存的多项式的项数,使用for语句,控制输入多项式的每一项。当创建的链表长度为n时,将不再提示用户继续输入多项式的系数和指数。建立一个一元多项式的单链表的具体算法如下://多项式链表的建立voidCreatPolyn(LinkList&L,intn){LinkListpa;//定义一个头指针为pa链表inti,q;//i用来计输入的项数,q指结点的位置序号DataTypee;//插入的值epa=(ListNode*)malloc(sizeof(ListNode));//生成链表头结点pa->next=NULL;for(i=1;i<=n;i++){scanf("%f,%d",&e.coef,&e.expn);if(!LocateNode(pa,e,q))//当前链表中不存在该指数项InsertNode(pa,e,q);//调用InsertNode函数插入结点}L=pa;(3)多项式链表的相加根据一元多项式相加的运算规则:对于一元多项式中所有指数相同的项,对应系数相加,若其和不为零,则构成“和多项式”中的一项;对于两个一元多项式中所有指数不相同的项,则分别复制到“和多项式”中相应的位置。根据以上运算规则,其实现算法思路如下:假设pc为指向“和多项式链表”当前尾结点的指针,指针pa和pb分别指向两个多项式中当前进行比较的某个结点,则比较两个结点中的指数项值,有下面三种情况:1.若指针pa所指结点的指数值大于指针pb所指结点的指数值,则取pa指针所指向的结点插入到pc指针所指结点之后,分别修改指针pa和pc,使之指向链表的下一个结点;2.若指针pa所指结点的指数值小于指针pb所指结点的指数值,则取pb指针所指向的结点插入到pc指针所指结点之后,分别修改指针pb和pc,使之指向链表的下一个结点;3.若指针pa所指结点的指数值等于指针pb所指结点的指数值,则将两结点中的系数相加,如果其和数不为零,则修改pa指针所指结点中的系数值,将其结点插入到pc指针所指结点之后,分别修改pa、pb和pc,使之指向各自链表的下一个结点,同时删除并释放指针pb原先指向各自链表的下一个结点;如果和数为零,保存pa和pb所指向的结点,修改pa和pb指针使之指向各自链表的下一个结点,然后释放保存的两个结点。再比较指针pa和pb指向节点中的指数项值,分3种情况进行处理⋯..这样的操作一直继续到pa或pb等于NULL为止。最后将未结束的链表后面剩余的节点连接到pc指针所指向结点之后。上述多项式的相加过程和两个有序链表合并的过程类似,不同之处仅在于多项式的比较多了相等比较后的操作。因此,多项式相加的过程完全可以利用线性链表的基本操作来实现。具体实现多项式相加的算法如下://多项式链表的相加voidAddPolyn(LinkListLa,LinkListLb,LinkList&Lc){//两个有序链表La和Lb表示的多项式相加ListNode*pa,*pb,*pc,*s;floatsum;pa=La->next;pb=Lb->next;//pa和pb分别指向两个链表的开始结点Lc=pc=La;//用La的头结点作为Lc的头结点while(pa&&pb){if(pa->data.expn>pb->data.expn){pc->next=pa;pc=pa;pa=pa->next;}elseif(pa->data.expndata.expn){pc->next=pb;pc=pb;pb=pb->next;}else{sum=pa->data.coef+pb->data.coef;if(fabs(sum)>0){//系数和不为零pa->data.coef=sum;pc->next=pa;pc=pa;pa=pa->next;s=pb;pb=pb->next;free(s);}else{s=pa;pa=pa->next;free(s);s=pb;pb=pb->next;free(s);}}}pc->next=pa?pa:pb;//插入链表剩余部分free(Lb);//释放Lb的头结点}(4)多项式链表的输出voidprintList(LinkListL)函数功能:显示多项式链表。在输出项中使用了条件表达式,当系数项为正数时,在系数前输出一个“+”号,否则输出一个空格,而负数的负号还照常输出,使得输出结果尽量与原多项式的表示形式类似。因此,输出多项式链表的算法实现如下://多项式链表的输出voidprintList(LinkListL){p=L->next;while(p){printf("%c%fx^%d",(p->data.coef>0?'+':''),p->data.coef,p->data.expn);p=p->next;}printf("\n");}源程序代码:#include#include#include//多项式链表结点类型定义typedefstruct//在struct前使用关键字typedef,表示是声明新类型{floatcoef;//系数intexpn;//指数}DataType;//DataType是新类型typedefstructnode//单链表的存储{DataTypedata;//数据域structnode*next;//指向下一个结点}ListNode,*LinkList;//ListNode是结点的新类型,LinkList是指向ListNode类型的结点的指针类型//结点的查找定位intLocateNode(LinkListL,DataTypee,int&q){ListNode*p=L->next;q=0;//记录结点位置序号while(p&&e.expndata.expn){p=p->next;q++;}if(p==NULL||e.expn!=p->data.expn)return0;elsereturn1;}//有序链表结点的插入voidInsertNode(LinkList&L,DataTypee,intq){inti=0;p=L;while(p->next&&i{p=p->next;i++;}s=(ListNode*)malloc(sizeof(ListNode));s->data.coef=e.coef;s->data.expn=e.expn;s->next=p->next;p->next=s;}//多项式链表的建立voidCreatPolyn(LinkList&L,intn){LinkListpa;//定义一个头指针为pa链表inti,q;//i用来计输入的项数,q指结点的位置序号DataTypee;//插入的值epa=(ListNode*)malloc(sizeof(ListNode));//生成链表头结点pa->next=NULL;scanf("%f,%d",&e.coef,&e.expn);if(!LocateNode(pa,e,q))//当前链表中不存在该指数项InsertNode(pa,e,q);//调用InsertNode函数插入结点}L=pa;}//多项式链表的输出voidprintList(LinkListL){ListNode*p;p=L->next;while(p){printf("%c%fx^%d",(p->data.coef>0?'+':''),p->data.coef,p->data.expn);p=p->next;}printf("\n");}//多项式链表的相加voidAddPolyn(LinkListLa,LinkListLb,LinkList&Lc){//两个有序链表La和Lb表示的多项式相加floatsum;pa=La->next;pb=Lb->next;//pa和pb分别指向两个链表的开始结点Lc=pc=La;//用La的头结点作为Lc的头结点while(pa&&pb){if(pa->data.expn>pb->data.expn){pc->next=pa;pc=pa;pa=pa->next;}elseif(pa->data.expndata.expn){pc->next=pb;pc=pb;pb=pb->next;}else{sum=pa->data.coef+pb->data.coef;if(fabs(sum)>0){//系数和不为零pa->data.coef=sum;pc->next=pa;pc=pa;pa=pa->next;s=pb;pb=pb->next;free(s);}else{s=pa;pa=pa->next;free(s);s=pb;pb=pb->next;free(s);}}}pc->next=pa?pa:pb;//插入链表剩余部分free(Lb);//释放Lb的头结点}//主控函数voidmain(){LinkListLa,Lb,Lc;intn;printf("输入第一个多项式的项数:");scanf("%d",&n);指数:\n");指数:");printf("输入第一个多项式的每一项的系数CreatPolyn(La,n);printf("第一个多项式为:");printList(La);printf("输入第二个多项式的项数:");scanf("%d",&n);printf("输入第二个多项式的每一项的系数CreatPolyn(Lb,n);printf("第二个多项式为:");printList(Lb);AddPolyn(La,Lb,Lc);printf("\n相加后的和多项式为:");printList(Lc);}5、调试分析此一元多项式的运算程序,只能实现一元多项式的加、减法,不能实现一元多项式的乘法,而且若想计数多个多项式的和或者差的话,必须退出界面重新开始计算。在补充程序里面,解决了程序没有的选择功能表的功能,及其多项式的乘法运算。6.测试结果输入多项式的项数,并且显示多项式及其两个多项式的和:补充程序:多项式运算程序具有以下基本功能:1.界面输出,提示如何输入数据。要求先输入多项式的项数。2.创建多项式。接收输入的数据,并保存到链表中。3.显示程序的功能表,允许使用者选择运算类型。4.显示已经创建好的多项式。5.实现加法运算。6.实现减法运算。7.实现乘法运算。8.清除内存内容,销毁创建的链表,退出程序。该程序实现了多项式的创建、多项式的加法、减法、乘法运算以及多项式的清除。源程序代码:#include#include********************//*该函数的功能:在计算机内要表示一个多项式,至少以下数据信息--系数信息、指数信息和指向下一个单项式的指针。通过指针,我们就可以把多个单项式连接起来,形式一个多项式.*/typedefstructPolynomial{floatcoef;//系数intexpn;//指数structPolynomial*next;//指向下一个结点}*Polyn,Polynomial;//Polyn为结点指针类型/**************以下函数用来实现链表的顺序排列和合并相同的项***************//*该函数的功能:实现链表的顺序排列和合并相同的项。将新的节点p插入到现有链表的后面,并确保多项式的指数expn是升序。将p节点插入到head所指向的链表。在该函数的操作中,要注意指针是如何移动的。*/voidInsert(Polynp,Polynh){if(p->coef==0)free(p);//系数为0的话释放结点else//如果系数不为0{q1=h;q2=h->next;{q1=q2;q2=q2->next;}if(q2&&p->expn==q2->expn)//将指数相同相合并{q2->coef+=p->coef;free(p);if(!q2->coef)//系数为0的话释放结点{q1->next=q2->next;free(q2);}}else//指数为新时将结点插入{p->next=q2;q1->next=p;}}}//Insert以下函数实现建立一个多项式/*该函数功能:创建新的多项式链表。intm保存的多项式的项数,使用for语句,控制输入多项式的每一项。当创建的链表长度为m时,将不再提示用户继续输入多项式的系数和指数。*/PolynCreatePolyn(Polynhead,intm)//建立一个头指针为head、项数为m的一元多项式,intm是保存的多项式的项数{//在主程序初始时,先输入的多项式中的项数m、n在这里为m。主程序中的pa、pb在此为headinti;//定义inti计数,当i当i=m时,输入完毕,该链表也创建完毕。Polynp;//定义一个p链表p=head=(Polyn)malloc(sizeof(structPolynomial));head->next=NULL;for(i=0;i当创建的链表长度为m时,将不再提示用户继续输入多项式的系数和指数。{p=(Polyn)malloc(sizeof(structPolynomial));//建立新结点以接收数据,用到分配空间的函数malloc()为新建链表分配空间printf("请输入第%d项的系数与指数:",i+1);scanf("%f%d",&p->coef,&p->expn);Insert(p,head);//调用Insert函数插入结点}returnhead;}//CreatePolyn以下函数实现多项式的销毁/*该函数的功能:销毁掉创建的两个链表,释放内存。以辅助退出程序*/voidDestroyPolyn(Polynp)//销毁多项式p{Polynq1,q2;q1=p->next;q2=q1->next;while(q1->next){free(q1);q1=q2;//指针后移q2=q2->next;}}以下函数实现显示输出多项式*******************/尤其是第/*该函数的功能:显示多项式链表。在该函数中较复杂的是如何控制链表的输出项的输出,同时还有符号的控制。在输出第一项时要判断是不是常数项,若是,则不要输出字符x。*/voidPrintPolyn(PolynP){Polynq=P->next;intflag=1;//项数计数器,flag=1表示为第一项if(!q)//若多项式为空,输出0{putchar('0');printf("\n");return;}while(q){if(q->coef>0&&flag!=1)//系数大于0且不是第一项putchar('+');if(q->coef!=1&&q->coef!=-1)//系数非1或-1的普通情况{printf("%g",q->coef);if(q->expn==1)putchar('X');elseif(q->expn)printf("X^%d",q->expn);else{if(q->coef==1){if(!q->expn)putchar('1');elseif(q->expn==1)putchar('X');elseprintf("X^%d",q->expn);}if(q->coef==-1){if(!q->expn)printf("-1");elseif(q->expn==1)printf("-X");elseprintf("-X^%d",q->expn);}}q=q->next;flag++;}//whileprintf("\n");}//PrintPolyn0
i++;
}//查找插入位置
s=(ListNode*)malloc(sizeof(ListNode));
s->data.coef=e.coef;
s->data.expn=e.expn;
s->next=p->next;
p->next=s;
}有了上述两个“结点的查找定位算法”和“有序链表结点的插入算法”,
intn保存的多项式的项数,使用for语句,控制输入多项式的每一项。
当创建的链表长度为n时,将不再提示用户继续输入多项式的系数和指数。
建立一个一元多项式的单链表的具体算法如下:
//多项式链表的建立
voidCreatPolyn(LinkList&L,intn)
LinkListpa;//定义一个头指针为pa链表
inti,q;//i用来计输入的项数,q指结点的位置序号
DataTypee;//插入的值epa=(ListNode*)malloc(sizeof(ListNode));//生成链表头结点pa->next=NULL;
for(i=1;i<=n;i++)
scanf("%f,%d",&e.coef,&e.expn);
if(!
LocateNode(pa,e,q))//当前链表中不存在该指数项
InsertNode(pa,e,q);//调用InsertNode函数插入结点
L=pa;
(3)多项式链表的相加
根据一元多项式相加的运算规则:
对于一元多项式中所有指数相同的项,对应系数相加,若其和不为零,则构成“和多项式”中的一项;对于两个一元多项式中所有指数不相同的项,则分别复制到“和多项式”中相应的位置。
根据以上运算规则,其实现算法思路如下:
假设pc为指向“和多项式链表”当前尾结点的指针,指针pa和pb分别指向两个多项式中当前进行比较的某个结点,则比较两个结点中的指数项值,有下面三种情况:
1.若指针pa所指结点的指数值大于指针pb所指结点的指数值,则取pa指针所指向的结点插入到pc指针所指结点之后,分别修改指针pa和pc,使之指向链表的下一个结点;
2.若指针pa所指结点的指数值小于指针pb所指结点的指数值,则取pb指针所指向的结点插入到pc指针所指结点之后,分别修改指针pb和pc,使之指向链表的下一个结点;
3.若指针pa所指结点的指数值等于指针pb所指结点的指数值,则将两结点中的系数相加,如果其和数不为零,则修改pa指针所指结点中的系数值,将其结点插入到pc指针所指结点之后,分别修改pa、pb和pc,使之指向各自链表的下一个结点,同时删除并释放指针pb原先指向各自链表的下一个结点;如果和数为零,保存pa和pb所指向的结点,
修改pa和pb指针使之指向各自链表的下一个结点,然后释放保存的两个结点。
再比较指针pa和pb指向节点中的指数项值,分3种情况进行处理⋯..
这样的操作一直继续到pa或pb等于NULL为止。
最后将未结束的链表后面剩余的节点连接到pc指针所指向结点之后。
上述多项式的相加过程和两个有序链表合并的过程类似,不同之处仅在于多项式的比较多了相等比较后的操作。
因此,多项式相加的过程完全可以利用线性链表的基本操作来实现。
具体实现多项式相加的算法如下:
//多项式链表的相加
voidAddPolyn(LinkListLa,LinkListLb,LinkList&Lc)
{//两个有序链表La和Lb表示的多项式相加
ListNode*pa,*pb,*pc,*s;
floatsum;
pa=La->next;pb=Lb->next;//pa和pb分别指向两个链表的开始结点
Lc=pc=La;//用La的头结点作为Lc的头结点
while(pa&&pb)
if(pa->data.expn>pb->data.expn)
pc->next=pa;pc=pa;pa=pa->next;
elseif(pa->data.expndata.expn)
pc->next=pb;pc=pb;pb=pb->next;
else{
sum=pa->data.coef+pb->data.coef;
if(fabs(sum)>0)
{//系数和不为零
pa->data.coef=sum;
s=pb;pb=pb->next;free(s);
}else{s=pa;pa=pa->next;free(s);s=pb;pb=pb->next;free(s);
pc->next=pa?
pa:
pb;//插入链表剩余部分free(Lb);//释放Lb的头结点
(4)多项式链表的输出
voidprintList(LinkListL)函数功能:
显示多项式链表。
在输出项中使用了条件表达式,当系数项为正数时,在系数前输出一个“+”号,否则输出一个空格,而负数的负号还照常输出,使得输出结果尽量与原多项式的表示形式类似。
因此,输出多项式链表的算法实现如下:
//多项式链表的输出
voidprintList(LinkListL)
p=L->next;
while(p)
printf("%c%fx^%d",(p->data.coef>0?
'+':
''),p->data.coef,p->data.expn);
printf("\n");
源程序代码:
#include
//多项式链表结点类型定义
typedefstruct
//在struct前使用关键字typedef,表示是声明新类型
}DataType;//DataType是新类型
while(p->next&&i{p=p->next;i++;}s=(ListNode*)malloc(sizeof(ListNode));s->data.coef=e.coef;s->data.expn=e.expn;s->next=p->next;p->next=s;}//多项式链表的建立voidCreatPolyn(LinkList&L,intn){LinkListpa;//定义一个头指针为pa链表inti,q;//i用来计输入的项数,q指结点的位置序号DataTypee;//插入的值epa=(ListNode*)malloc(sizeof(ListNode));//生成链表头结点pa->next=NULL;scanf("%f,%d",&e.coef,&e.expn);if(!LocateNode(pa,e,q))//当前链表中不存在该指数项InsertNode(pa,e,q);//调用InsertNode函数插入结点}L=pa;}//多项式链表的输出voidprintList(LinkListL){ListNode*p;p=L->next;while(p){printf("%c%fx^%d",(p->data.coef>0?'+':''),p->data.coef,p->data.expn);p=p->next;}printf("\n");}//多项式链表的相加voidAddPolyn(LinkListLa,LinkListLb,LinkList&Lc){//两个有序链表La和Lb表示的多项式相加floatsum;pa=La->next;pb=Lb->next;//pa和pb分别指向两个链表的开始结点Lc=pc=La;//用La的头结点作为Lc的头结点while(pa&&pb){if(pa->data.expn>pb->data.expn){pc->next=pa;pc=pa;pa=pa->next;}elseif(pa->data.expndata.expn){pc->next=pb;pc=pb;pb=pb->next;}else{sum=pa->data.coef+pb->data.coef;if(fabs(sum)>0){//系数和不为零pa->data.coef=sum;pc->next=pa;pc=pa;pa=pa->next;s=pb;pb=pb->next;free(s);}else{s=pa;pa=pa->next;free(s);s=pb;pb=pb->next;free(s);}}}pc->next=pa?pa:pb;//插入链表剩余部分free(Lb);//释放Lb的头结点}//主控函数voidmain(){LinkListLa,Lb,Lc;intn;printf("输入第一个多项式的项数:");scanf("%d",&n);指数:\n");指数:");printf("输入第一个多项式的每一项的系数CreatPolyn(La,n);printf("第一个多项式为:");printList(La);printf("输入第二个多项式的项数:");scanf("%d",&n);printf("输入第二个多项式的每一项的系数CreatPolyn(Lb,n);printf("第二个多项式为:");printList(Lb);AddPolyn(La,Lb,Lc);printf("\n相加后的和多项式为:");printList(Lc);}5、调试分析此一元多项式的运算程序,只能实现一元多项式的加、减法,不能实现一元多项式的乘法,而且若想计数多个多项式的和或者差的话,必须退出界面重新开始计算。在补充程序里面,解决了程序没有的选择功能表的功能,及其多项式的乘法运算。6.测试结果输入多项式的项数,并且显示多项式及其两个多项式的和:补充程序:多项式运算程序具有以下基本功能:1.界面输出,提示如何输入数据。要求先输入多项式的项数。2.创建多项式。接收输入的数据,并保存到链表中。3.显示程序的功能表,允许使用者选择运算类型。4.显示已经创建好的多项式。5.实现加法运算。6.实现减法运算。7.实现乘法运算。8.清除内存内容,销毁创建的链表,退出程序。该程序实现了多项式的创建、多项式的加法、减法、乘法运算以及多项式的清除。源程序代码:#include#include********************//*该函数的功能:在计算机内要表示一个多项式,至少以下数据信息--系数信息、指数信息和指向下一个单项式的指针。通过指针,我们就可以把多个单项式连接起来,形式一个多项式.*/typedefstructPolynomial{floatcoef;//系数intexpn;//指数structPolynomial*next;//指向下一个结点}*Polyn,Polynomial;//Polyn为结点指针类型/**************以下函数用来实现链表的顺序排列和合并相同的项***************//*该函数的功能:实现链表的顺序排列和合并相同的项。将新的节点p插入到现有链表的后面,并确保多项式的指数expn是升序。将p节点插入到head所指向的链表。在该函数的操作中,要注意指针是如何移动的。*/voidInsert(Polynp,Polynh){if(p->coef==0)free(p);//系数为0的话释放结点else//如果系数不为0{q1=h;q2=h->next;{q1=q2;q2=q2->next;}if(q2&&p->expn==q2->expn)//将指数相同相合并{q2->coef+=p->coef;free(p);if(!q2->coef)//系数为0的话释放结点{q1->next=q2->next;free(q2);}}else//指数为新时将结点插入{p->next=q2;q1->next=p;}}}//Insert以下函数实现建立一个多项式/*该函数功能:创建新的多项式链表。intm保存的多项式的项数,使用for语句,控制输入多项式的每一项。当创建的链表长度为m时,将不再提示用户继续输入多项式的系数和指数。*/PolynCreatePolyn(Polynhead,intm)//建立一个头指针为head、项数为m的一元多项式,intm是保存的多项式的项数{//在主程序初始时,先输入的多项式中的项数m、n在这里为m。主程序中的pa、pb在此为headinti;//定义inti计数,当i当i=m时,输入完毕,该链表也创建完毕。Polynp;//定义一个p链表p=head=(Polyn)malloc(sizeof(structPolynomial));head->next=NULL;for(i=0;i当创建的链表长度为m时,将不再提示用户继续输入多项式的系数和指数。{p=(Polyn)malloc(sizeof(structPolynomial));//建立新结点以接收数据,用到分配空间的函数malloc()为新建链表分配空间printf("请输入第%d项的系数与指数:",i+1);scanf("%f%d",&p->coef,&p->expn);Insert(p,head);//调用Insert函数插入结点}returnhead;}//CreatePolyn以下函数实现多项式的销毁/*该函数的功能:销毁掉创建的两个链表,释放内存。以辅助退出程序*/voidDestroyPolyn(Polynp)//销毁多项式p{Polynq1,q2;q1=p->next;q2=q1->next;while(q1->next){free(q1);q1=q2;//指针后移q2=q2->next;}}以下函数实现显示输出多项式*******************/尤其是第/*该函数的功能:显示多项式链表。在该函数中较复杂的是如何控制链表的输出项的输出,同时还有符号的控制。在输出第一项时要判断是不是常数项,若是,则不要输出字符x。*/voidPrintPolyn(PolynP){Polynq=P->next;intflag=1;//项数计数器,flag=1表示为第一项if(!q)//若多项式为空,输出0{putchar('0');printf("\n");return;}while(q){if(q->coef>0&&flag!=1)//系数大于0且不是第一项putchar('+');if(q->coef!=1&&q->coef!=-1)//系数非1或-1的普通情况{printf("%g",q->coef);if(q->expn==1)putchar('X');elseif(q->expn)printf("X^%d",q->expn);else{if(q->coef==1){if(!q->expn)putchar('1');elseif(q->expn==1)putchar('X');elseprintf("X^%d",q->expn);}if(q->coef==-1){if(!q->expn)printf("-1");elseif(q->expn==1)printf("-X");elseprintf("-X^%d",q->expn);}}q=q->next;flag++;}//whileprintf("\n");}//PrintPolyn0
{p=p->next;i++;}s=(ListNode*)malloc(sizeof(ListNode));s->data.coef=e.coef;s->data.expn=e.expn;s->next=p->next;p->next=s;}//多项式链表的建立voidCreatPolyn(LinkList&L,intn){LinkListpa;//定义一个头指针为pa链表inti,q;//i用来计输入的项数,q指结点的位置序号DataTypee;//插入的值epa=(ListNode*)malloc(sizeof(ListNode));//生成链表头结点pa->next=NULL;scanf("%f,%d",&e.coef,&e.expn);if(!LocateNode(pa,e,q))//当前链表中不存在该指数项InsertNode(pa,e,q);//调用InsertNode函数插入结点}L=pa;}//多项式链表的输出voidprintList(LinkListL){ListNode*p;p=L->next;while(p){printf("%c%fx^%d",(p->data.coef>0?'+':''),p->data.coef,p->data.expn);p=p->next;}printf("\n");}//多项式链表的相加voidAddPolyn(LinkListLa,LinkListLb,LinkList&Lc){//两个有序链表La和Lb表示的多项式相加floatsum;pa=La->next;pb=Lb->next;//pa和pb分别指向两个链表的开始结点Lc=pc=La;//用La的头结点作为Lc的头结点while(pa&&pb){if(pa->data.expn>pb->data.expn){pc->next=pa;pc=pa;pa=pa->next;}elseif(pa->data.expndata.expn){pc->next=pb;pc=pb;pb=pb->next;}else{sum=pa->data.coef+pb->data.coef;if(fabs(sum)>0){//系数和不为零pa->data.coef=sum;pc->next=pa;pc=pa;pa=pa->next;s=pb;pb=pb->next;free(s);}else{s=pa;pa=pa->next;free(s);s=pb;pb=pb->next;free(s);}}}pc->next=pa?pa:pb;//插入链表剩余部分free(Lb);//释放Lb的头结点}//主控函数voidmain(){LinkListLa,Lb,Lc;intn;printf("输入第一个多项式的项数:");scanf("%d",&n);指数:\n");指数:");printf("输入第一个多项式的每一项的系数CreatPolyn(La,n);printf("第一个多项式为:");printList(La);printf("输入第二个多项式的项数:");scanf("%d",&n);printf("输入第二个多项式的每一项的系数CreatPolyn(Lb,n);printf("第二个多项式为:");printList(Lb);AddPolyn(La,Lb,Lc);printf("\n相加后的和多项式为:");printList(Lc);}5、调试分析此一元多项式的运算程序,只能实现一元多项式的加、减法,不能实现一元多项式的乘法,而且若想计数多个多项式的和或者差的话,必须退出界面重新开始计算。在补充程序里面,解决了程序没有的选择功能表的功能,及其多项式的乘法运算。6.测试结果输入多项式的项数,并且显示多项式及其两个多项式的和:补充程序:多项式运算程序具有以下基本功能:1.界面输出,提示如何输入数据。要求先输入多项式的项数。2.创建多项式。接收输入的数据,并保存到链表中。3.显示程序的功能表,允许使用者选择运算类型。4.显示已经创建好的多项式。5.实现加法运算。6.实现减法运算。7.实现乘法运算。8.清除内存内容,销毁创建的链表,退出程序。该程序实现了多项式的创建、多项式的加法、减法、乘法运算以及多项式的清除。源程序代码:#include#include********************//*该函数的功能:在计算机内要表示一个多项式,至少以下数据信息--系数信息、指数信息和指向下一个单项式的指针。通过指针,我们就可以把多个单项式连接起来,形式一个多项式.*/typedefstructPolynomial{floatcoef;//系数intexpn;//指数structPolynomial*next;//指向下一个结点}*Polyn,Polynomial;//Polyn为结点指针类型/**************以下函数用来实现链表的顺序排列和合并相同的项***************//*该函数的功能:实现链表的顺序排列和合并相同的项。将新的节点p插入到现有链表的后面,并确保多项式的指数expn是升序。将p节点插入到head所指向的链表。在该函数的操作中,要注意指针是如何移动的。*/voidInsert(Polynp,Polynh){if(p->coef==0)free(p);//系数为0的话释放结点else//如果系数不为0{q1=h;q2=h->next;{q1=q2;q2=q2->next;}if(q2&&p->expn==q2->expn)//将指数相同相合并{q2->coef+=p->coef;free(p);if(!q2->coef)//系数为0的话释放结点{q1->next=q2->next;free(q2);}}else//指数为新时将结点插入{p->next=q2;q1->next=p;}}}//Insert以下函数实现建立一个多项式/*该函数功能:创建新的多项式链表。intm保存的多项式的项数,使用for语句,控制输入多项式的每一项。当创建的链表长度为m时,将不再提示用户继续输入多项式的系数和指数。*/PolynCreatePolyn(Polynhead,intm)//建立一个头指针为head、项数为m的一元多项式,intm是保存的多项式的项数{//在主程序初始时,先输入的多项式中的项数m、n在这里为m。主程序中的pa、pb在此为headinti;//定义inti计数,当i当i=m时,输入完毕,该链表也创建完毕。Polynp;//定义一个p链表p=head=(Polyn)malloc(sizeof(structPolynomial));head->next=NULL;for(i=0;i当创建的链表长度为m时,将不再提示用户继续输入多项式的系数和指数。{p=(Polyn)malloc(sizeof(structPolynomial));//建立新结点以接收数据,用到分配空间的函数malloc()为新建链表分配空间printf("请输入第%d项的系数与指数:",i+1);scanf("%f%d",&p->coef,&p->expn);Insert(p,head);//调用Insert函数插入结点}returnhead;}//CreatePolyn以下函数实现多项式的销毁/*该函数的功能:销毁掉创建的两个链表,释放内存。以辅助退出程序*/voidDestroyPolyn(Polynp)//销毁多项式p{Polynq1,q2;q1=p->next;q2=q1->next;while(q1->next){free(q1);q1=q2;//指针后移q2=q2->next;}}以下函数实现显示输出多项式*******************/尤其是第/*该函数的功能:显示多项式链表。在该函数中较复杂的是如何控制链表的输出项的输出,同时还有符号的控制。在输出第一项时要判断是不是常数项,若是,则不要输出字符x。*/voidPrintPolyn(PolynP){Polynq=P->next;intflag=1;//项数计数器,flag=1表示为第一项if(!q)//若多项式为空,输出0{putchar('0');printf("\n");return;}while(q){if(q->coef>0&&flag!=1)//系数大于0且不是第一项putchar('+');if(q->coef!=1&&q->coef!=-1)//系数非1或-1的普通情况{printf("%g",q->coef);if(q->expn==1)putchar('X');elseif(q->expn)printf("X^%d",q->expn);else{if(q->coef==1){if(!q->expn)putchar('1');elseif(q->expn==1)putchar('X');elseprintf("X^%d",q->expn);}if(q->coef==-1){if(!q->expn)printf("-1");elseif(q->expn==1)printf("-X");elseprintf("-X^%d",q->expn);}}q=q->next;flag++;}//whileprintf("\n");}//PrintPolyn0
DataTypee;//插入的值e
pa=(ListNode*)malloc(sizeof(ListNode));//生成链表头结点
pa->next=NULL;
ListNode*p;
pa=La->next;pb=Lb->next;//pa
和pb分别指向两个链表的开始结点
Lc=pc=La;//用La的头结点作为Lc的头结点while(pa&&pb)
pc->next=pa;pc=pa;pa=pa->next;s=pb;pb=pb->next;free(s);
s=pa;pa=pa->next;free(s);
pb;//插入链表剩余部分
free(Lb);//释放Lb的头结点
//主控函数
voidmain()
LinkListLa,Lb,Lc;
intn;
printf("输入第一个多项式的项数:
");
scanf("%d",&n);
指数:
\n");
printf("输入第一个多项式的每一项的系数
CreatPolyn(La,n);
printf("第一个多项式为:
printList(La);
printf("输入第二个多项式的项数:
printf("输入第二个多项式的每一项的系数
CreatPolyn(Lb,n);
printf("第二个多项式为:
printList(Lb);
AddPolyn(La,Lb,Lc);
printf("\n相加后的和多项式为:
printList(Lc);
5、调试分析
此一元多项式的运算程序,只能实现一元多项式的加、减法,不能实现一元多项式的
乘法,而且若想计数多个多项式的和或者差的话,必须退出界面重新开始计算。
在补充程序里面,解决了程序没有的选择功能表的功能,及其多项式的乘法运算。
6.测试结果
输入多项式的项数,并且显示多项式及其两个多项式的和:
补充程序:
多项式运算程序具有以下基本功能:
1.界面输出,提示如何输入数据。
2.创建多项式。
3.显示程序的功能表,允许使用者选择运算类型。
4.显示已经创建好的多项式。
5.实现加法运算。
6.实现减法运算。
7.实现乘法运算。
8.清除内存内容,销毁创建的链表,退出程序。
该程序实现了多项式的创建、多项式的加法、减法、乘法运算以及多项式的清除。
********************/
/*该函数的功能:
在计算机内要表示一个多项式,至少以下数据信息--系数信息、指数信息和指向下一个单项式的指针。
通过指针,我们就可以把多个单项式连接起来,形式一个多项式.*/typedefstructPolynomial
structPolynomial*next;//指向下一个结点}*Polyn,Polynomial;//Polyn为结点指针类型
/**************以下函数用来实现链表的顺序排列和合并相同的项***************/
实现链表的顺序排列和合并相同的项。
将新的节点p插入到现有链表的后
面,并确保多项式的指数
expn是升序。
将p节点插入到head所指向的链表。
*/voidInsert(Polynp,Polynh)
if(p->coef==0)
free(p);//系数为0的话释放结点
else//如果系数不为0
q1=h;q2=h->next;
q1=q2;
q2=q2->next;
if(q2&&p->expn==q2->expn)//将指数相同相合并
q2->coef+=p->coef;
free(p);
q2->coef)//系数为0的话释放结点
q1->next=q2->next;
free(q2);
else//指数为新时将结点插入
p->next=q2;
q1->next=p;
}//Insert
以下函数实现建立一个多项式
/*该函数功能:
创建新的多项式链表。
intm保存的多项式的项数,使用for语句,控制输入多项式的每一项。
当创建的链表长度为m时,将不再提示用户继续输入多项式的系数和指数。
*/
PolynCreatePolyn(Polynhead,intm)//建立一个头指针为head、项数为m的一元多项
式,intm是保存的多项式的项数
//在主程序初始时,先输入的多项式中的项数m、n在这里为m。
主程序中的pa、pb在此为head
inti;//定义inti计数,当i当i=m时,输入完毕,该链表也创建完毕。Polynp;//定义一个p链表p=head=(Polyn)malloc(sizeof(structPolynomial));head->next=NULL;for(i=0;i当创建的链表长度为m时,将不再提示用户继续输入多项式的系数和指数。{p=(Polyn)malloc(sizeof(structPolynomial));//建立新结点以接收数据,用到分配空间的函数malloc()为新建链表分配空间printf("请输入第%d项的系数与指数:",i+1);scanf("%f%d",&p->coef,&p->expn);Insert(p,head);//调用Insert函数插入结点}returnhead;}//CreatePolyn以下函数实现多项式的销毁/*该函数的功能:销毁掉创建的两个链表,释放内存。以辅助退出程序*/voidDestroyPolyn(Polynp)//销毁多项式p{Polynq1,q2;q1=p->next;q2=q1->next;while(q1->next){free(q1);q1=q2;//指针后移q2=q2->next;}}以下函数实现显示输出多项式*******************/尤其是第/*该函数的功能:显示多项式链表。在该函数中较复杂的是如何控制链表的输出项的输出,同时还有符号的控制。在输出第一项时要判断是不是常数项,若是,则不要输出字符x。*/voidPrintPolyn(PolynP){Polynq=P->next;intflag=1;//项数计数器,flag=1表示为第一项if(!q)//若多项式为空,输出0{putchar('0');printf("\n");return;}while(q){if(q->coef>0&&flag!=1)//系数大于0且不是第一项putchar('+');if(q->coef!=1&&q->coef!=-1)//系数非1或-1的普通情况{printf("%g",q->coef);if(q->expn==1)putchar('X');elseif(q->expn)printf("X^%d",q->expn);else{if(q->coef==1){if(!q->expn)putchar('1');elseif(q->expn==1)putchar('X');elseprintf("X^%d",q->expn);}if(q->coef==-1){if(!q->expn)printf("-1");elseif(q->expn==1)printf("-X");elseprintf("-X^%d",q->expn);}}q=q->next;flag++;}//whileprintf("\n");}//PrintPolyn0
当i=m时,输入完毕,该链表也创建完毕。
Polynp;//定义一个p链表
p=head=(Polyn)malloc(sizeof(structPolynomial));
head->next=NULL;
for(i=0;i当创建的链表长度为m时,将不再提示用户继续输入多项式的系数和指数。{p=(Polyn)malloc(sizeof(structPolynomial));//建立新结点以接收数据,用到分配空间的函数malloc()为新建链表分配空间printf("请输入第%d项的系数与指数:",i+1);scanf("%f%d",&p->coef,&p->expn);Insert(p,head);//调用Insert函数插入结点}returnhead;}//CreatePolyn以下函数实现多项式的销毁/*该函数的功能:销毁掉创建的两个链表,释放内存。以辅助退出程序*/voidDestroyPolyn(Polynp)//销毁多项式p{Polynq1,q2;q1=p->next;q2=q1->next;while(q1->next){free(q1);q1=q2;//指针后移q2=q2->next;}}以下函数实现显示输出多项式*******************/尤其是第/*该函数的功能:显示多项式链表。在该函数中较复杂的是如何控制链表的输出项的输出,同时还有符号的控制。在输出第一项时要判断是不是常数项,若是,则不要输出字符x。*/voidPrintPolyn(PolynP){Polynq=P->next;intflag=1;//项数计数器,flag=1表示为第一项if(!q)//若多项式为空,输出0{putchar('0');printf("\n");return;}while(q){if(q->coef>0&&flag!=1)//系数大于0且不是第一项putchar('+');if(q->coef!=1&&q->coef!=-1)//系数非1或-1的普通情况{printf("%g",q->coef);if(q->expn==1)putchar('X');elseif(q->expn)printf("X^%d",q->expn);else{if(q->coef==1){if(!q->expn)putchar('1');elseif(q->expn==1)putchar('X');elseprintf("X^%d",q->expn);}if(q->coef==-1){if(!q->expn)printf("-1");elseif(q->expn==1)printf("-X");elseprintf("-X^%d",q->expn);}}q=q->next;flag++;}//whileprintf("\n");}//PrintPolyn0
p=(Polyn)malloc(sizeof(structPolynomial));//建立新结点以接收数据,用到分配空间的函数malloc()为新建链表分配空间
printf("请输入第%d项的系数与指数:
",i+1);
scanf("%f%d",&p->coef,&p->expn);
Insert(p,head);//调用Insert函数插入结点
returnhead;
}//CreatePolyn
以下函数实现多项式的销毁
销毁掉创建的两个链表,释放内存。
以辅助退出程序*/
voidDestroyPolyn(Polynp)//销毁多项式p
Polynq1,q2;q1=p->next;q2=q1->next;
while(q1->next)
free(q1);
q1=q2;//指针后移
以下函数实现显示输出多项式*******************/
尤其是第
在该函数中较复杂的是如何控制链表的输出
项的输出,同时还有符号的控制。
在输出第一项时要判断是不是常数项,若是,则不要输出字符x。
voidPrintPolyn(PolynP){
Polynq=P->next;
intflag=1;//项数计数器,flag=1表示为第一项
q)//若多项式为空,输出0
putchar('0');
return;
while(q)
if(q->coef>0&&flag!
=1)//系数大于0且不是第一项putchar('+');
if(q->coef!
=1&&q->coef!
=-1)//系数非1或-1的普通情况{
printf("%g",q->coef);
if(q->expn==1)
putchar('X');
elseif(q->expn)
printf("X^%d",q->expn);
if(q->coef==1)
q->expn)
putchar('1');
elseif(q->expn==1)
if(q->coef==-1)
printf("-1");
elseif(q->expn==1)printf("-X");
printf("-X^%d",q->expn);
q=q->next;
flag++;
}//while
}//PrintPolyn
0
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1