程序要求
掌握线性表的链式存储结构的表示和实现方法以及链表基本操作的算法,应用线性表链式存储结构解决实际问题——一元稀疏多项式的计算。要求利用线性表的链式存储结构实现多项式的存储、输出显示、相加、相减、相乘。
算法分析
多项式加法
若pa指向元素的指数小于pb指向元素的指数, 则结点pa所指的结点应是“和多项式”中的一项,令指针pa、pc后移, pb 不变;
若pa指向元素的指数大于pb指向元素的指数,则结点pb所指的结点应是“和多项式”中的一项, 将结点pb插入在结点pa之前,pb 、pc后移, pa 不变;
若pa指向元素的指数与pb指向元素的指数相等, 则将两个结点中的系数相加, 释放pb结点;当和不为零时修改结点pa的系数域, pa、pc后移;若和为零,释放pa,pa后移。
多项式减法
与多项式加法类似,不过需要注意插入元素时候应取系数的相反数。
多项式乘法
对于A和B中的节点,系数相加,指数相乘,到已有乘积链表中查找,如果有相同指数的项就合并,合并后的项系数为0就删除,如果没有相同指数的项就插入到合适位置
核心程序
#include <stdio.h>
#include <malloc.h>
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
typedef int status ;
#define ERROR -1
#define OK 1
struct nodeElem{
float coef; //系数
int expn;
};
//typedef int ElemType;
typedef nodeElem ElemType;
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
typedef LinkList polynomial;
void outElem1(ElemType e){
printf("%fx^%d",e.coef,e.expn);
}
void printlist_L1(polynomial L)
{//L为带头结点的单链表的头指针
//输出每一个节点的data
LNode *p;
p=L->next;
printf("P(x)=");
while(p!=NULL)
{
//printf("%d ",p->data);
outElem1(p->data);
p=p->next;
if(p==NULL)break;
printf("+");
}
printf("\n");
}
void outElem2(ElemType e){
printf("%f %d ",e.coef,e.expn);
}
void printlist_L2(polynomial L)
{//L为带头结点的单链表的头指针
//输出每一个节点的data
LNode *p;
p=L->next;
while(p!=NULL)
{
outElem2(p->data);
p=p->next;
}
printf("\n");
}
status GetElem_L(LinkList L,int i,ElemType &e)
{//L为带头结点的单链表的头指针
//当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR
LNode *p;
int j;
p=L->next; j=1;
while(p&&j<i)
{p=p->next; ++j;}
if (!p||j>i) return ERROR;
e=p->data;
return OK;
}
void printlist_L(LinkList L)
{//L为带头结点的单链表的头指针
//输出每一个节点的data
LNode *p;
p=L->next;
//printf("(");
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
//printf(")");
printf("\n");
}
status length_L(LinkList L)
{//L为带头结点的单链表的头指针
//输出每一个节点的data
LNode *p;
int num=0;
p=L->next;
while(p!=NULL)
{
num++;
p=p->next;
}
return num;
}
void CreateList_L(LinkList &L,ElemType a[],int n)
{//逆位序输入n个元素的值,建立带头结点的单链表L
LNode *p;
int i;
L=(LinkList) malloc(sizeof(LNode));
L->next=NULL;
for(i=n-1;i>=0;--i)
{p=(LinkList)malloc(sizeof(LNode));
//scanf("%d",&p->data);
p->data=a[i];
p->next=L->next;
L->next=p;
}
}//CreateList_L
status ListInsert_L(LinkList &L,int i,ElemType e)
{//在带头结点的单链表L中第i个位置之前插入元素e
LNode *p,*s;
int j;
p=L; j=0;
while (p!=NULL && j<i-1) {p=p->next; ++j;}
if (p==NULL||j>i-1) return ERROR;
s=(LinkList)malloc(sizeof(LNode));
s->data=e;
s->next=p->next;
p->next=s;
return OK;
}//ListInsert_L
status ListDelete_L(LinkList &L,int i,ElemType &e)
{//在带头结点的单链表L中,删除第i个元素,并由e返回其值
LNode *p,*q;
int j;
p=L; j=0;
while (p->next && j<i-1)
{p=p->next; ++j;}
if (!(p->next)||j>i-1) return ERROR;
q=p->next;
p->next=q->next;
e=q->data;
free(q);
return OK;
}//ListDelete_L
LinkList AddPolyn(LinkList &A,LinkList &B)
{
LNode *pa,*pb,*pc,*p;
pa=A->next;
pb=B->next;
pc=A;
p=B;free(p);
while((pa!=NULL)&&(pb!=NULL))
{
if((pa->data.expn)<(pb->data.expn))
{
pc->next=pa;
pc=pa;
pa=pa->next;
}
else if((pa->data.expn)>(pb->data.expn))
{
pc->next=pb;
pc=pb;
pb=pb->next;
}
else
{
if((pa->data.expn)==(pb->data.expn))
{
pa->data.coef=(pa->data.coef)+(pb->data.coef);
p=pb;
pb=pb->next;
free(p);
//if((pa->data.coef)+(pb->data.coef)==0)
if(pa->data.coef==0)
{
p=pa;
pa=pa->next;
free(p);
}
else
{
//pa->data.coef=pb->data.coef;
pc->next=pa;
pc=pa;
pa=pa->next;
}
}
}
}
if(pa!=NULL)pc->next=pa;
else pc->next=pb;
return A;
}
LinkList SubPolyn(LinkList &A,LinkList &B)
{
LNode *pa,*pb,*pc,*p;
pa=A->next;
pb=B->next;
pc=A;
p=B;free(p);
ElemType e;
int i;
while((pa!=NULL)&&(pb!=NULL))
{
if((pa->data.expn)<(pb->data.expn))
{
//pb->data.coef=-(pb->data.coef);
pc->next=pa;
pc=pa;
pa=pa->next;
}
else if((pa->data.expn)>(pb->data.expn))
{
pb->data.coef=-(pb->data.coef);
pc->next=pb;
pc=pb;
pb=pb->next;
}
else
{
if((pa->data.expn)==(pb->data.expn))
{
pb->data.coef=-(pb->data.coef);
pa->data.coef=(pa->data.coef)+(pb->data.coef);
p=pb;
pb=pb->next;
free(p);
//if((pa->data.coef)+(pb->data.coef)==0)
if(pa->data.coef==0)
{
p=pa;
pa=pa->next;
free(p);
}
else
{
//pa->data.coef=pb->data.coef;
pc->next=pa;
pc=pa;
pa=pa->next;
}
}
}
}
if(pa!=NULL)pc->next=pa;
else
{
pc->next=pb;
while(pc!=NULL)
{
pc->data.coef=-(pc->data.coef);
pc=pc->next;
}
}
return A;
}
LinkList MultiPolyn(LinkList &A,LinkList &B)
{
LNode *pa,*pb,*pc,*p,*q;
pa=A->next;
pb=B->next;
pc=A;
LinkList D;
D=(LinkList) malloc(sizeof(LNode));
D->next=NULL;
//p=B;free(p);
while(pa!=NULL)
{
while(pb!=NULL)
{
ElemType item; //算出一项
item.coef=(pa->data.coef)*(pb->data.coef);//系数相乘
item.expn=(pa->data.expn)+(pb->data.expn);//指数相加
LNode *pre=D,*r=pre->next;
while(r&&r->data.expn!=item.expn)
//到已有乘积链表中查找与item有相同指数的r,pre是r的前驱,方便删除r
{ //outElem(p->data);
pre=r;r=r->next;
}
if(r!=NULL) //到已有乘积链表中查找item,如果有相同指数的项就合并
{
// outElem(p->data);
r->data.coef=r->data.coef+item.coef;
if(r->data.coef==0) {pre->next=r->next;free(r);} //合并后的项系数为0就删除
}
else //如果没有相同指数的项就插入到合适位置。
{//insertElem(D,item);
//ListInsert_Lp(D,item);
pre=D; r=pre->next;
while (r!=NULL && r->data.expn<item.expn)
//找指数大于item的指数的第一个节点r,pre是r的前驱,r可能为空,pre不可能为空,item插入到pre之后
{pre=r;r=r->next;}
p=(LinkList)malloc(sizeof(LNode));
p->data=item;
p->next=pre->next;
pre->next=p;}
// p=(LinkList) malloc(sizeof(LNode));
// p->data.coef=(pa->data.coef)*(pb->data.coef);//系数相乘
// p->data.expn=(pa->data.expn)+(pb->data.expn);//指数相加
// p->next=D->next;
// D->next=p;
pb=pb->next;
}
pa=pa->next;
pb=B->next;
}
return D;
}
int main()
{
ElemType aa[4]={{5,1},{8,3},{2,4},{-4,6}};
ElemType bb[5]={{3,0},{-8,3},{3,4},{-2,8},{-8,9}};
int b[5]={1,5,6,8,10},num;
int test1[10]={0,1,2,3,4,5,6,7,8,9};
int test2[5]={1,3,5,7,9};
int e,length,del,m;
LinkList L,La,Lb,Lc,Lx,Ly;
printf("----Polynomial Calculator----:\n");
printf("Please choose the mode:(1:Add,2:Sub,3:Multi)\n");
scanf("%d",&m);
if(m==1)
{
CreateList_L(La,aa,4);
printlist_L2(La);
CreateList_L(Lb,bb,5);
printlist_L2(Lb);
printf("A+B is:");
Lc=AddPolyn(La,Lb);
printlist_L1(Lc);
printf("\n");
}
if(m==2)
{
CreateList_L(La,aa,4);
printlist_L2(La);
CreateList_L(Lb,bb,5);
printlist_L2(Lb);
printf("A-B is:");
Lc=SubPolyn(La,Lb);
printlist_L1(Lc);
printf("\n");
}
if(m==3)
{
CreateList_L(La,aa,4);
printlist_L2(La);
CreateList_L(Lb,bb,5);
printlist_L2(Lb);
printf("A*B is:");
Lc=MultiPolyn(La,Lb);
printf("multy=");
printlist_L1(Lc);
}
return 0;
}
运行结果
选择模式(1)为多项式加法,输出结果为A+B
选择模式(2)为多项式减法,输出结果为A-B
选择模式(3)为多项式乘法,输出结果为A*B