1.一元多项式的表示
可采用线性表的顺序存储结构,但是当多项式的每个项的指数差别很大时,会浪费很多存储空间。所以采用链式存储方式表示,每一项可以表示成一个结点,结点的结构由存放系数的coed域,存放指数的expn域和指向下一个结点的next指针域组成。
例如,多项式
S(x)=7x6+3x4−3x2+6
可以表示成链表。
2.一元多项式的相乘
两个一元多项式的相乘运算,需要将一个多项式的每一项的指数与另一个多项式的每一项的质数相加,并将其系数相乘。
例如两个多项式A(x)和B(x)相乘后得到C(x)。
A(x)=4x4+3x2+5x
,
B(x)=6x3+7x2+8x
,
C(x)=24x7+28x6+50x5+51x4+59x3+40x2
表示成链式存储结构如下图所示。
算法思想:设A、B和C分别是多项式A(x)、B(x)和C(x)对应链表的头指针,要计算出A(x)和B(x)的最高指数和,即4+3=7,则A(x)和B(x)的乘机C(x)的指数范围在0~7之间。然后将A(x)的各项按照指数降幂排列,将B(x)按照指数升幂排列,分别设两个指针pa和pb,pa用来指向链表A,pb用来指向链表B,从第一个结点开始计算两个链表的expn域的和,并将其与k比较(k为指数和的范围,从7到0递减),使链表的和呈递减排列。若和小于k,则pb=pb->next;若和等于k,则求出两个多项式系数的乘积,并将其存入新结点中。若和大于k,则pa=pa->next。这样就可以得到多项式 A(x)和B(x)的乘积C(x)。算法结束后重新将链表B逆置,将其恢复原样。
- 类型定义
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
/*一元多项式结点类型定义*/
typedef struct polyn
{
float coef; /*存放一元多项式的系数*/
int expn; /*存放一元多项式的指数*/
struct polyn *next;
}PolyNode, *PLinkList;
- 函数文件
void OutPut(PLinkList head)
/*输出一元多项式*/
{
PolyNode *p=head->next;
while(p)
{
printf("%1.1f",p->coef);
if(p->expn)
printf("*x^%d",p->expn);
if(p->next&&p->next->coef>0)
printf("+");
p=p->next;
}
}
PLinkList CreatePolyn()
/*创建一元多项式,使一元多项式呈指数递减*/
{
PolyNode *p,*q,*s;
PolyNode *head=NULL;
int expn2;
float coef2;
head=(PLinkList)malloc(sizeof(PolyNode)); /*动态生成一个头结点*/
if(!head)
return NULL;
head->coef=0;
head->expn=0;
head->next=NULL;
do
{
printf("输入系数coef(系数和指数都为0结束)");
scanf("%f",&coef2);
printf("输入指数exp(系数和指数都为0结束)");
scanf("%d",&expn2);
if((long)coef2==0&&expn2==0)
break;
s=(PolyNode*)malloc(sizeof(PolyNode));
if(!s)
return NULL;
s->expn=expn2;
s->coef=coef2;
q=head->next; /*q指向链表的第一个结点,即表尾*/
p=head; /*p指向q的前驱结点*/
while(q&&expn2<q->expn) /*将新输入的指数与q指向的结点指数比较*/
{
p=q;
q=q->next;
}
if(q==NULL||expn2>q->expn) /*q指向要插入结点的位置,p指向要插入结点的前驱*/
{
p->next=s; /*将s结点插入到链表中*/
s->next=q;
}
else
q->coef+=coef2; /*如果指数与链表中结点指数相同,则将系数相加即可*/
} while(1);
return head;
}
PolyNode *Reverse(PLinkList head)
/*将生的的链表逆置,使一元多项式呈指数递增形式*/
{
PolyNode *q,*r,*p=NULL;
q=head->next;
while(q)
{
r=q->next; /*r指向链表的待处理结点*/
q->next=p; /*将链表结点逆置*/
p=q; /*p指向刚逆置后链表结点*/
q=r; /*q指向下一准备逆置的结点*/
}
head->next=p; /*将头结点的指针指向已经逆置后的链表*/
return head;
}
PolyNode *MultiplyPolyn(PLinkList A,PLinkList B)
/*多项式的乘积。*/
{
PolyNode *pa,*pb,*pc,*u,*head;
int k,maxExp;
float coef;
head=(PLinkList)malloc(sizeof(PolyNode)); /*动态生成头结点*/
if(!head)
return NULL;
head->coef=0.0;
head->expn=0;
head->next=NULL;
if(A->next!=NULL&&B->next!=NULL)
maxExp=A->next->expn+B->next->expn; /*maxExp为两个链表指数的和的最大值*/
else
return head;
pc=head;
B=Reverse(B); /*使多项式B(x)呈指数递增形式*/
for(k=maxExp;k>=0;k--) /*多项式的乘积指数范围为0-maxExp*/
{
pa=A->next;
while(pa!=NULL&&pa->expn>k) /*找到pa的位置*/
pa=pa->next;
pb=B->next;
while(pb!=NULL&&pa!=NULL&&pa->expn+pb->expn<k)/*如果和小于k,使pb移到下一个结点*/
pb=pb->next;
coef=0.0;
while(pa!=NULL&&pb!=NULL)
{
if(pa->expn+pb->expn==k) /*如果在链表中找到对应的结点,即和等于k,求相应的系数*/
{
coef+=pa->coef*pb->coef;
pa=pa->next;
pb=pb->next;
}
else if(pa->expn+pb->expn>k) /*如果和大于k,则使pa移到下一个结点*/
pa=pa->next;
else
pb=pb->next; /*如果和小于k,则使pb移到到下一个结点*/
}
if(coef!=0.0)
/*如果系数不为0,则生成新结点,并将系数和指数分别赋值给新结点。并将结点插入到链表中*/
{
u=(PolyNode*)malloc(sizeof(PolyNode));
u->coef=coef;
u->expn=k;
u->next=pc->next;
pc->next=u;
pc=u;
}
}
B=Reverse(B); /*完成多项式乘积后,将B(x)呈指数递减形式*/
return head;
}
- 主程序
void main()
{
PLinkList A,B,C;
A=CreatePolyn();
printf("A(x)=");
OutPut(A);
printf("\n");
B=CreatePolyn();
printf("B(x)=");
OutPut(B);
printf("\n");
C=MultiplyPolyn(A,B);
printf("C(x)=A(x)*B(x)=");
OutPut(C); /*输出结果*/
printf("\n");
}
- 测试结果