问题描述
设Pn(x)和Qm(x)分别两个一元多项式。试编写程序实现一元多项式的加法运算。
基本要求
需要基于线性表的基本操作来实现一元多项式的加法运算
需要利用有序链表来实现线性表。 (注意此处!顺序链表的意思就是你的节点数据必须是有序的!)
一、问题分析:
一元多项式就是说类似于这样的式子:2x^3+3x^6......未知数只有一个的式子。我的思路是基于链表来实现,两个多项式分别用链表去存储,计算得到的结果再用一个链表去存储,总共要使用三个链表。
二、具体实现:
怎么生成链表我就不说了,详见上一篇博客。接下来重点讲的是两个链表相加的情况,要是考虑不齐全就会出错。首先两个多项式的长度不一定相等,因此要分成一下三种情况:(1)两个多项式,只有多项式A;(2)两个多项式,只有多项式B(3)两个多项式存储在。因为要求实现是有序链表,因此两个多项式相加的时候,最好从最大的幂或者最大的系数开始加,具体何种顺序自己定,我这里是按照幂的大到小。
不多说,贴代码:
Link* Link::Add(Link* A,Link* B)
{
Link* C = new Link;
C->next = NULL;//创建一个C链表
Link* p1 = A->next;
Link* p2 = B->next;
Link* p3;
Link* rearC=C;//初始化C链表(头尾一样,链表为空)
while(p1!=NULL&&p2!=NULL)//情况3
{
if(p1->exp>p2->exp)
{
p3 = new Link;//申请一个新节点
p3->exp = p1->exp;
p3->cofe = p1->cofe;
p3->next=NULL;//方便下一个节点链接
rearC->next=p3;//插入到C链表的尾部
rearC=p3;
p1=p1->next ;//寻找下一个
}
else if(p1->exp<p2->exp)
{
p3 = new Link;//申请一个新节点
p3->exp = p2->exp;
p3->cofe = p2->cofe;
p3->next=NULL;//方便下一个节点链接
rearC->next=p3;//插入到C链表的尾部
rearC=p3;
p2=p2->next ;//寻找下一个
}
else
{
if(p1->cofe+p2->cofe!=0)
{
p3 = new Link;
p3->exp = p1->exp;
p3->cofe= p1->cofe+p2->cofe;
p3->next=NULL;
rearC->next=p3;
rearC=p3;
}
p1=p1->next;
p2=p2->next;
}
}
if(p1==NULL) 情况2
{
while(p2!=NULL)
{
p3=new Link;
p3->cofe=p2->cofe;
p3->exp=p2->exp;
p3->next=NULL;
rearC->next=p3;
rearC=p3;
p2=p2->next;
}
}
else //p2==NULL 情况1
{
while(p1!=NULL)
{
p3=new Link;
p3->cofe=p1->cofe;
p3->exp=p1->exp;
p3->next=NULL;
rearC->next=p3;
rearC=p3;
p1=p1->next;
}
}
return C; //返回整个链表
}
哦对了,为了节省相加的时候比较数据大小的时间,可以在链表数据录入的时候就进行排序,就是拿现在输入的exp和已经录入链表的尾部节点的exp比较(基于尾插法)如果小于就交换一下两个节点。
具体代码如下:
cin>>n>>e;
Link* new_node=new Link;
new_node->cofe=n;
new_node->exp=e;
now_node=head->next;
if(now_node==NULL)//如果是第一个节点,也就是还没有头节点
{
new_node->next=NULL;
head->next=new_node;
continue;
}
else
{
now_node=head;//初始化开始找的位置为头节点
while(now_node!=NULL)//没有找到尾部节点时
{
if(now_node->next==NULL || (now_node->exp>e&&now_node->next->exp<e))//自己定的顺序规则这里的if条件就是满足 前一个点的exp >待插入节点的exp >前一个节点的下一个节点的exp,也就是能插入两个节点中间的情况,这个情况适合链表所有的位置。精华所在啊!!找了好久bug。
{
new_node->next=now_node->next;//连接
now_node->next=new_node;//更新节点的位置,方便下一次进入,节省时间,你就把它想象成链表上的一根定位针就好了。
break;
}
now_node=now_node->next;//节点递增
}
}
}
其它就很简单了,不再过多赘述。
附录完整代码:
//main.cpp
#include<iostream>
#include"Link.h"
using namespace std;
int main()
{
cout<<"请输入第一个多项式的项数:"<<endl;
Link* P1;
P1=P1->Creat();
cout<<"生成的多项式A为:"<<endl;
P1->Display(P1);
cout<<"请输入第二个多项式的项数:"<<endl;
Link* P2;
P2=P2->Creat();
cout<<"生成的多项式B为:"<<endl;
P2->Display(P2);
cout<<"多项式A+B为:"<<endl;
Link* P3=P1->Add(P1,P2);
P3->Display(P3);
return 0;
}
//Link.h
#ifndef _LINK_H_INCLUDE
#define _LINK_H_INCLUDE
class Link{
private:
int exp;
int cofe;
Link* next;
public:
Link();
~Link();
Link* Add(Link* A,Link* B);
Link* Creat();
void Display(Link* P);
};
#endif
//Link.cpp
#include<iostream>
#include"Link.h"
using namespace std;
Link::Link()
{
this->next=NULL;
this->cofe=cofe;
this->exp=exp;
}
Link* Link::Add(Link* A,Link* B)
{
Link* C = new Link;
C->next = NULL;//创建一个C链表
Link* p1 = A->next;
Link* p2 = B->next;
Link* p3;
Link* rearC=C;//初始化C链表(头尾一样,链表为空)
while(p1!=NULL&&p2!=NULL)
{
if(p1->exp>p2->exp)
{
p3 = new Link;//申请一个新节点
p3->exp = p1->exp;
p3->cofe = p1->cofe;
p3->next=NULL;//方便下一个节点链接
rearC->next=p3;//插入到C链表的尾部
rearC=p3;
p1=p1->next ;//寻找下一个
}
else if(p1->exp<p2->exp)
{
p3 = new Link;//申请一个新节点
p3->exp = p2->exp;
p3->cofe = p2->cofe;
p3->next=NULL;//方便下一个节点链接
rearC->next=p3;//插入到C链表的尾部
rearC=p3;
p2=p2->next ;//寻找下一个
}
else
{
if(p1->cofe+p2->cofe!=0)
{
p3 = new Link;
p3->exp = p1->exp;
p3->cofe= p1->cofe+p2->cofe;
p3->next=NULL;
rearC->next=p3;
rearC=p3;
}
p1=p1->next;
p2=p2->next;
}
}
if(p1==NULL)
{
while(p2!=NULL)
{
p3=new Link;
p3->cofe=p2->cofe;
p3->exp=p2->exp;
p3->next=NULL;
rearC->next=p3;
rearC=p3;
p2=p2->next;
}
}
else //p2==NULL
{
while(p1!=NULL)
{
p3=new Link;
p3->cofe=p1->cofe;
p3->exp=p1->exp;
p3->next=NULL;
rearC->next=p3;
rearC=p3;
p1=p1->next;
}
}
return C; //返回整个链表
}
Link* Link::Creat()
{
Link* head;
Link* new_node=new Link;
Link* now_node=new Link;
head=new Link;//申请一个头结点
head->next=NULL;//初始化头结点指针
head->exp=1e9;
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cout<<"请输入第 "<<i+1<<" 项的系数和指数(输入完成按回车)"<<endl;
int e,n;
cin>>n>>e;
Link* new_node=new Link;
new_node->cofe=n;
new_node->exp=e;
now_node=head->next;
if(now_node==NULL)
{
new_node->next=NULL;
head->next=new_node;
continue;
}
else
{
now_node=head;
while(now_node!=NULL)
{
if(now_node->next==NULL || (now_node->exp>e&&now_node->next->exp<e))
{
new_node->next=now_node->next;
now_node->next=new_node;
break;
}
now_node=now_node->next;
}
}
}
return head;
}
void Link::Display(Link* head)
{
if(head==NULL)
{
cout<<"多项式不存在!"<<endl;
return ;
}
Link* p;
p=head->next;
while(p!=NULL)
{
if(p->cofe>0)
{
cout<<p->cofe<<"x^"<<p->exp;
}
else
{
cout<<"("<<p->cofe<<")"<<"x^"<<p->exp;
}
if(p->next!=NULL)
{
cout<<"+";
}
p=p->next;
}
cout<<endl;
}