一元多项式的表示及相加
在数学上,一个一元多项式Pn(x)可以按照升幂写成:
Pn(x)=p0+p1x+p2x^2+....pnx^n
这个表达式由系数(coef),指数(expn)两部分组成,由此我们可以用链表(带有头结点)表示一个一元多项式,如下:
采用上述链表方式,我们可以创建两个链表来分别存放两个一元多项式表达式,然后再将他们相加,减,乘后的结果分别保存到新创建的链表中。
具体实现如下:
Polynomial_AddSubMult.h头文件:
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define EPS 0.000001 //判断系数是否为0
typedef struct Polynomial
{
float coef;//系数
int expn;//指数
struct Polynomial *next;
}Polynomial,*LinkList;
void InitLinkList(LinkList Head);//初始化链表(带有头结点)
//输入一元多项式的系数,指数(按照多项式指数升幂输入)
void InsertTail(LinkList Head,float ceof,int expn);
//完成一元多项式的加法运算Result_Add = Headf + heafg;
void AddPolynomial(LinkList Headf,LinkList Headg,LinkList Result_Add);
//完成一元多项式的减法运算Result_Sub = Headf - heafg;
void SubPolynomial(LinkList Headf,LinkList Headg,LinkList Result_Sub);
//完成一元多项式的乘法运算Result_Mult = Headf * heafg;
void MultPolynomial(LinkList Headf,LinkList Headg,LinkList Result_Mult,LinkList Headd,LinkList Headd2);
int GetLegth(LinkList Head);
int IsEmpty(LinkList Head);
void Delete_Head(LinkList plist);
void Clear(LinkList Head);
void Destory(LinkList Head);
void Show(LinkList Head);
函数说明:Polynomial_AddSubMult.c
#include"Polynomial_AddSubMult.h"
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<math.h>
static LinkList _ApplyNode(float ceof,int expn,LinkList next)//申请空间,作为内部函数,不能对外访问
{
LinkList s = (LinkList)malloc(sizeof(Polynomial));
if(s == NULL)
{
printf("_ApplyNode:Application Node Failed\n");
return NULL;
}
s->coef = ceof;
s->expn = expn;
s->next = next;
return s;
}
void InitLinkList(LinkList Head)
{
assert(Head != NULL);
if(Head == NULL)
{
printf("InitLinkList:Empty HeadNode\n");
return ;
}
Head->next = NULL;
}
void InsertTail(LinkList Head,float ceof,int expn)
{
assert(Head != NULL);
if(Head == NULL)
{
printf("InsertTail:Empty HeadNode\n");
return ;
}
LinkList p = Head;
while (p->next != NULL)
{
p = p->next;
}
p->next = _ApplyNode(ceof,expn,NULL);
}
//完成一元多项式的加法运算Headr = Headf + heafg;
void AddPolynomial(LinkList Headf,LinkList Headg,LinkList Result_Add)
{
if(Headf == NULL || Headg == NULL || Result_Add == NULL)
{
printf("AddPolynomial:Empty LinkList\n");
return;
}
LinkList pf = Headf->next,pg = Headg->next;
while (pf != NULL && pg != NULL)
{
if(pf->expn > pg->expn)
{
InsertTail(Result_Add,pg->coef ,pg->expn);
pg = pg->next;
}
else if(pf->expn < pg->expn)
{
InsertTail(Result_Add,pf->coef ,pf->expn);
pf = pf->next;
}
else
{
if ((pf->coef + pg->coef) > EPS)//防止两个表达式中出现指数相同,系数互为相反数的情况
{
InsertTail(Result_Add,pf->coef + pg->coef,pf->expn);
pf = pf->next;
pg = pg->next;
}
else
{
pf = pf->next;
pg = pg->next;
}
}
}
//下面两个while循环是表示如果还有一个表达式没有遍历完,可以最后直接插入到结果表达式结尾
while (pf != NULL)
{
InsertTail(Result_Add,pf->coef ,pf->expn);
pf = pf->next;
}
while (pg != NULL)
{
InsertTail(Result_Add,pg->coef ,pg->expn);
pg = pg->next;
}
}
//完成一元多项式的减法运算Result_Sub = Headf - heafg;
void SubPolynomial(LinkList Headf,LinkList Headg,LinkList Result_Sub)
{
if(Result_Sub == NULL || Headg == NULL || Headf == NULL)
{
printf("SubPolynomial:Empty LinkList\n");
return;
}
LinkList pf = Headf->next,pg = Headg->next;
while (pf != NULL && pg != NULL)
{
if(pf->expn > pg->expn)
{
InsertTail(Result_Sub,-pg->coef ,pg->expn);
pg = pg->next;
}
else if(pf->expn < pg->expn)
{
InsertTail(Result_Sub,pf->coef ,pf->expn);
pf = pf->next;
}
else if( (pf->coef - pg->coef) > EPS) //系数相减不为0
{
InsertTail(Result_Sub,pf->coef - pg->coef,pf->expn);
pf = pf->next;
pg = pg->next;
}
else if( (pg->coef - pf->coef) > EPS)
{
InsertTail(Result_Sub,pf->coef - pg->coef,pf->expn);
pf = pf->next;
pg = pg->next;
}
else
{
pf = pf->next;
pg = pg->next;
}
}
while (pf != NULL)
{
InsertTail(Result_Sub,pf->coef ,pf->expn);
pf = pf->next;
}
while (pg != NULL)
{
InsertTail(Result_Sub,-pg->coef ,pg->expn);
pg = pg->next;
}
}
//完成一元多项式的乘法运算Result_Mult = Headf * heafg;
void MultPolynomial(LinkList Headf,LinkList Headg,LinkList Result_Mult,LinkList Headd1,LinkList Headd2)
{
if(IsEmpty(Headf) || IsEmpty(Headg) || Result_Mult == NULL)
{
printf("MultPolynomial:Empty LinkList\n");
return;
}
LinkList pf = Headf->next,pg = Headg->next;
for(int i = 0;pf != NULL;pf = pf->next,i++)
{
Clear(Result_Mult);
for(pg = Headg->next;pg != NULL;pg = pg->next)
{
if(i % 2 == 0 )
{
InsertTail(Headd1,pf->coef * pg->coef,pf->expn + pg->expn);
}
else
{
InsertTail(Headd2,pf->coef * pg->coef,pf->expn + pg->expn);
}
}
AddPolynomial(Headd1,Headd2,Result_Mult);
Clear(Headd1);
Clear(Headd2);
if( i % 2 == 0)
{
LinkList s = Result_Mult->next;
while (s != NULL)
{
InsertTail(Headd1,s->coef,s->expn);
s = s->next;
}
}
else
{
LinkList s = Result_Mult->next;
while (s != NULL)
{
InsertTail(Headd2,s->coef,s->expn);
s = s->next;
}
}
}
}
//头删除,
void Delete_Head(LinkList plist)
{
assert(plist != NULL);
if(plist == NULL)
{
printf("The Single LinkList is NULL\n");
return;
}
LinkList q = plist->next;
if(q != NULL)
{
plist->next = q->next;
}
free(q);
}
void Clear(LinkList Head)
{
assert(Head != NULL);
if(Head == NULL)
{
printf("GetLegth:Empty HeadNode\n");
return ;
}
while (!IsEmpty(Head))
{
Delete_Head(Head);
}
}
int GetLegth(LinkList Head)
{
assert(Head != NULL);
if(Head == NULL)
{
printf("GetLegth:Empty HeadNode\n");
return 1;
}
int length = 0;
LinkList s = Head->next;
while (s != NULL)
{
length++;
s = s->next;
}
return length;
}
int IsEmpty(LinkList Head)
{
return (Head->next == NULL || Head == NULL);
}
void Destory(LinkList Head)
{
assert(Head != NULL);
if(Head == NULL)
{
printf("Destory:Empty HeadNode\n");
return ;
}
}
void Show(LinkList Head)
{
assert(Head != NULL);
if(Head == NULL)
{
printf("Show:Empty HeadNode\n");
return ;
}
LinkList p = Head->next;
while (p != NULL)
{
printf("%4.2fx^%d",p->coef,p->expn);
if(p->next != NULL)
{
if(p->next->coef > EOF)
{
printf(" + ");
}
}
p = p->next;
}
printf("\n");
}
主函数:main.c
#include"Polynomial_AddSubMult.h"
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
int main()
{
Polynomial Headf,Headg,Headd1,Headd2;
Polynomial Result_Add,Result_Sub,Result_Mult;//这里创建三个链表分别保存相加,减,乘后的结果,目的是使他们之间的结果互不影响
InitLinkList(&Headf);
InitLinkList(&Headg);
InitLinkList(&Headd1);
InitLinkList(&Headd2);
InitLinkList(&Result_Add);
InitLinkList(&Result_Sub);
InitLinkList(&Result_Mult);
//分别插入两个一元多项式的系数,指数
InsertTail(&Headf,3,0);
InsertTail(&Headf,6,3);
InsertTail(&Headf,4,5);
InsertTail(&Headg,2,0);
InsertTail(&Headg,3,1);
InsertTail(&Headg,8,2);
Show(&Headf);
Show(&Headg);
AddPolynomial(&Headf,&Headg,&Result_Add);
printf("一元多项式相加后的结果:");
Show(&Result_Add);
MultPolynomial(&Headf,&Headg,&Result_Mult,&Headd1,&Headd2);
printf("一元多项式相乘后的结果:");
Show(&Result_Mult);
SubPolynomial(&Headf,&Headg,&Result_Sub);
printf("一元多项式相减后的结果:");
Show(&Result_Sub);
Destory(&Headf);
Destory(&Headg);
Destory(&Headd1);
Destory(&Headd2);
Destory(&Result_Add);
Destory(&Result_Sub);
Destory(&Result_Mult);
return 0;
}
最后给出代码运行结果:
!!! 以上代码过于复杂,但有一个优点就是两个多项式之间的加、减、乘之间互相不影响,但会浪费大量空间。
以后我们给出优化代码来实现一元多向表达式的加、减、乘。