//链表学习:多项式应用
//通过引入InsertPoly函数来完成加法乘法操作
//以及类似功能的Creat()函数,使我的多项式按照指数下降的方式插入节点
//而不需要在输入时人为的控制
#include <iostream>
using namespace std;
//多项式ADT链表实现的类型声明
typedef struct Node* PtrToNode;
struct Node
{
int Coefficient;
int Exponent;
PtrToNode Next;
};
typedef PtrToNode Polynomial;
Polynomial Creat()
{
PtrToNode head,s,p,tmp;
head=new Node;
head->Next=NULL;
int c,e;
cout<<"Please input Coefficient and Exponent and end with 9999"<<endl;
cin>>c>>e;
//输入结束标志
while(c!=9999 && e!=9999){
s=new Node;
s->Coefficient=c;
s->Exponent=e;
s->Next=NULL;
p=head;
/*while(p->Next!=NULL){ //在尾部插入一个节点
p=p->Next;
}*/
//在新建多项式时,将多项式按照指数降序插入
//完全借用了InsertPoly函数
while(p->Next!=NULL){
if(p->Next->Exponent < s->Exponent){
tmp=p->Next;
p->Next=s;
s->Next=tmp;
break;
}else if(p->Next->Exponent==s->Exponent){
p->Next->Coefficient=(p->Next->Coefficient)+(s->Coefficient);
break;
}
p=p->Next;
}
if(p->Next==NULL){
p->Next=s;
}
cout<<"Please input Coefficient and Exponent and end with 9999"<<endl;
cin>>c>>e;
}
return head;
}
void Show(PtrToNode head)
{
if(head==NULL)
cout<<"there are none Polynomial!"<<endl;
PtrToNode p;//临时节点用来遍历每一个节点
p=head->Next;
while(p!=NULL){
if(p->Coefficient > 0)
cout<<p->Coefficient<<"x^"<<p->Exponent;
else
cout<<'('<<p->Coefficient<<"x^"<<p->Exponent;
if(p->Next!=NULL)
cout<<'+';
p=p->Next;
}
cout<<endl<<endl;
}
//之前出错的函数,思想没问题,但是实现中始终没有完成插入
//解决关键,p1的初始化,以及while循环的条件;给链表插入时,始终要从前面一个开始
//错误实例:PtrToNode p1=head->Next;while(p1!=NULL);当多项式为空时,或者未找到合适位置插入时
//需要将新节点插入末尾,但是此时p1=NULL;即便是可以将p1=p0;但是。。。早已和前面的链表失去了联系。。
//这块需要多想想
//退出循环两种情况:1.p1->Next=NULL,则将节点插入最后;2.成功插入,函数结束
//功能:将节点插入,完成指数降序,且合并同类项
//将新建节点插入特定的位置,要是有指数相同的,合并;两者都不满足,插入末尾
PtrToNode InsertPoly(PtrToNode head, PtrToNode p0)
{
PtrToNode p1=head;
PtrToNode tmp;
while(p1->Next!=NULL){
if(p1->Next->Exponent < p0->Exponent){ //这个实现很妙。。。只要p0比p1->Next大,则插入p1后面,p1->Next前面
tmp=p1->Next;
p1->Next=p0;
p0->Next=tmp;
break;
}else if(p1->Next->Exponent==p0->Exponent){
p1->Next->Coefficient=(p1->Next->Coefficient)+(p0->Coefficient);
break;
}
p1=p1->Next;
}
if(p1->Next==NULL){
p1->Next=p0;
}
return head;
}
//问题:在我的插入函数里,最后if语句里,插入一个节点的时候
//直接将p1->Next=p0,也就是当我的p0-Next!=NULL时,其实我插入的不只一个节点,而是将p0以后的整个链表插入
//解决:每次要插入时新建一个新节点,这个新节点Next=NULL;
//加法:我沿用了乘法的思想
//因为我在新建多项式时,完成了将指数降序排列
//因此,多项式加法可以直接将一个多项式,插入到另一个多项式
//而不是以前那种,直接对两个多项式从头开始遍历,然后归并
PtrToNode AddPoly( PtrToNode Poly1, PtrToNode Poly2)
{
PtrToNode p1=Poly1->Next;
while(p1!=NULL){
PtrToNode tmp = new Node;
tmp->Exponent=p1->Exponent;
tmp->Coefficient=p1->Coefficient;
tmp->Next = NULL;
InsertPoly(Poly2,tmp);
p1=p1->Next;
}
return Poly2;
}
PtrToNode ProPoly( PtrToNode Poly1, PtrToNode Poly2)
{
PtrToNode p3,p1=Poly1->Next, p2=Poly2->Next;//p3是一个动态的指向Node节点的指针
PtrToNode propoly = new Node;
propoly->Next = NULL;//propoly 代表了积多项式的头指针
//老版本未合并同类项时为了遍历propoly定义的r
//PtrToNode r=propoly; //r用来对和多项式进行增操作,关键是对r的移动。。。随着p3
while(p1!=NULL){
while(p2!=NULL){
p3=new Node;
p3->Coefficient=(p1->Coefficient)*(p2->Coefficient);
p3->Exponent=(p1->Exponent)+(p2->Exponent);
p3->Next=NULL;
//r->Next=p3;
//r=p3;
p2=p2->Next;
InsertPoly(propoly,p3);
}
//内层循环结束后一定要p2重新指向第二个多项式第一个节点
p2=Poly2->Next;
p1=p1->Next;
}
return propoly;
}
int main()
{
cout<<"PolyA:"<<endl;
PtrToNode PL1;
PL1=Creat();
cout<<"PolyA=";
Show(PL1);
cout<<"PolyB:"<<endl;
PtrToNode PL2;
PL2=Creat();
cout<<"PolyB=";
Show(PL2);
cout<<"Poly A*B=";
PtrToNode PL3=ProPoly(PL1,PL2);
Show(PL3);
cout<<"Poly A+B=";
PtrToNode PL4=AddPoly(PL1,PL2);
Show(PL4);
return 0;
}
链表应用--多项式加法、乘法
最新推荐文章于 2022-05-09 12:23:30 发布