例题: 设有两个一元多项式,将其进行相加。多项式如下:
设计思路:
依次比较Pa和Pb所指结点中的指数项,依Pa―>expn ( =、<、>) Pb―>expn等情况,再决定是将两系数域的数值相加(并判其和是否为0),还是将较高指数项的结点插入到新表C中。
设计的思路很简单,但是想要真正的实现它,就需要熟练的掌握链表的用法,如果对于一些无法理解的地方,可以动手画图来辅助理解。
因为要在这讲的很清楚需要许多步骤,这里就不一一赘述了,大家可以直接看代码,如果那里看不明白的都可以提出来:
结构体:
将单链表的每个结点对应着一元多项式中的一个非零项,它由三个域组成,分别表示非零项的系数、指数和指向下一个结点的指针。
typedef struct Term
{
float coef;//x前面的系数
int expn; //x的次方数
struct Term *next;
}*LinkList;
c++代码:
#include <iostream>
#include <malloc.h>
using namespace std;
typedef struct Term
{
float coef;//x前面的系数
int expn; //x的次方数
struct Term *next;
}*LinkList;
void CreateList_L(struct Term *&L,int n) //创建Pa,Pb
{
int i;
struct Term *p;
L=(struct Term *)malloc(sizeof(Term));//创建
L->next=NULL;
for(i=0;i<n;i++)
{
p=(struct Term *)malloc(sizeof(Term));//创建
cout<<"coef = ";
cin>>p->coef; //输入coef
cout<<"expn = ";
cin>>p->expn; //输入expn
p->next=L->next; //相当于把p->next后面连上L->next后面所连接的
L->next=p; //将L->next指向P
}
if(n) cout<<"Success to Create a LinkList !"<<endl;
else cout<<"A NULL LinkList have been created !"<<endl;
}
char cmp(int qa_expn,int qb_expn) //判断qa,qb的expn的关系
{
if(qa_expn==qb_expn)
return '=';
else
if(qa_expn>qb_expn) return '>';
else return '<';
}
struct Term *AddPolyn(struct Term * &Pa,struct Term * &Pb)//进行判断相加
{
struct Term *qa,*qb,*pre,*qc,*s,*u;
float sum;
qc = new struct Term;
qc->next = NULL;
pre=qc;
qa=Pa->next;
qb=Pb->next;
while(qa&&qb)//只要qa,qb有一个不指向NULL,就加入循环
{
switch(cmp(qa->expn,qb->expn))
{
case '<': //qa的expn小于qb的expn
u = new struct Term;
u->coef = qa->coef;
u->expn = qa->expn;
u->next = NULL;
pre->next = u;
pre = u;
qa=qa->next;
break;
case '=': //qa,qb相加,之后同时往后移一位
sum=qa->coef+qb->coef;
if(sum!=0.0)
{
u = new struct Term;
u->coef = sum;
u->expn = qa->expn;
u->next = NULL;
pre->next = u;
pre = u;
}
qa = qa->next;
qb = qb->next;
break;
case '>': //qa的expn大于qb的expn
u = new struct Term;
u->coef = qb->coef;
u->expn = qb->expn;
u->next = NULL;
pre->next = u;
pre = u;
qb = qb->next;
break;
}
}
if(qa) s = qa;
else s = qb;
while(s)
{
u = new struct Term;
u->coef = s->coef;
u->expn = s->expn;
u->next = NULL;
pre->next = u;
pre = u;
s = s->next;
}
return qc;
}
void Sort(struct Term *p,int n) //判断多项式是否有相同的expn,有进行相加
{
struct Term *temp,*qa,*qb;
temp=(struct Term*)malloc(sizeof(Term));
for(int i=0;i<n-1;i++)
{
qa = p;
qb = p;
for(int j=0;j<n-1-i;j++)
{
qa=qa->next;
qb=qa->next;
if(qa->expn > qb->expn)
{
temp->coef=qa->coef;
qa->coef=qb->coef;
qb->coef=temp->coef;
temp->expn=qa->expn;
qa->expn=qb->expn;
qb->expn=temp->expn;
}
else if(qa->expn==qb->expn)
{
qa->coef += qb->coef;
qa->next = qb->next;
free(qb);
}
}
}
}
int Length(struct Term *p) //输出多项式项数
{
int Length = 0;
p = p->next;
if(!p) return 0;
while(p)
{
Length++;
p = p->next;
}
return Length;
}
void Print(struct Term *p) //打印输出多项式
{
while(p->next)
{
p = p->next;
if(p->next)
cout<<p->coef<<"*x^"<<p->expn<<"+";
else cout<<p->coef<<"*x^"<<p->expn;
}
}
int main()
{
struct Term *Pa,*Pb,*Pc;
int InitLNodeNum_Pa,InitLNodeNum_Pb,Length_Pc;
cout<<endl<<"输入Pa的个数 : ";
cin>>InitLNodeNum_Pa;
cout<<"输入Pa.coef 和 Pa.expn 的值(正序):"<<endl;
CreateList_L(Pa,InitLNodeNum_Pa);
cout<<endl<<"输入Pb的个数 : ";
cin>>InitLNodeNum_Pb;
cout<<"输入Pb.coef 和 Pb.expn 的值(正序):"<<endl;
CreateList_L(Pb,InitLNodeNum_Pb);
Pc = AddPolyn(Pa,Pb);
Length_Pc = Length(Pc);
Sort(Pc,Length_Pc);
Sort(Pa,InitLNodeNum_Pa);
Sort(Pb,InitLNodeNum_Pb);
cout<<endl<<"Result:"<<endl;
cout<<endl<<"输出Pc"<<endl;
Print(Pc);
//输出pa pb 验证原方程没有被破坏
cout<<endl<<"输出Pa"<<endl;
Print(Pa);
cout<<endl<<"输出Pb"<<endl;
Print(Pb);
cout<<endl<<"OK...!"<<endl;
return 0;
}
总结:
1.对于相加的结果大家可以自己进行尝试。
2.本题运用的链表,大家需要多去理解链表的使用方法,对于一些比较难理解的地方,大家可以进行画图来进行辅助理解。
3.需要注意的是,在这个源码中数据需要用升序的顺序来输入,如果想要实现乱序的输入,则需要在源码中写一个排序的函数,将它变成升序,在进行运算。