一、题目
依次输入两个多项式的项数,然后输入每一项的系数和指数,用空格隔开。
结果给出两个多项式相加的系数和指数。
二、解析
思路:
(1)结构体包括三部分,系数、指数和next指针
(2)写一个创建单链表的函数,先询问用户多项式的项数,然后从首元结点开始依次存储每一项的系数和指数
(3)我用链表a去存储结果。两链表a,b比较时,需要三个指针。anow指向链表a当前需要比较的结点,bnow指向链表b当前需要比较的结点,因为后面的分析中需要用到前插法将结点插入a中,所以还需要anow的前驱结点apre。
(4)分为三种情况:
①当anow->指数等于bnow->指数时,将他们的系数直接相加,存入anow中;anow和abnow都后移一次
②当anow->指数小于bnow->指数时,anow后移一位,bnow不变
③当anow->指数大于bnow->指数时,将bnow插入anow中(这里采用生成bnow的替身的形式,bnow本身位置没有变化),bnow后移一位
当链表a或者b为NULL时,表明存在一个链表遍历到头了。如果是a遍历完了的话,就要把b剩下的连到a的后面去;如果是b遍历完了的话,那刚刚好
三、简单版代码
#include<bits/stdc++.h>
using namespace std;
typedef struct PNode{
int exp; //指数
int coef; //系数
struct PNode *next; //指针域
}PNode,*Poly;
void create(Poly &p){
p=new PNode; //头指针指向头结点
p->next=NULL; //头结点指向空
Poly pre=p;
cout<<"请输入多项式的项数:"<<endl;
int n;
cin>>n;
for(int i=1;i<=n;i++){
Poly s=new PNode;
cin>>s->coef>>s->exp; //按照指数有小到大输入
s->next=NULL;
pre->next=s;
pre=s;
}
}
void add(Poly &a,Poly &b){ //把a当做存放结果的链表
Poly anow=a->next; //指向首元结点
Poly apre=a; //指向头结点
Poly bnow=b->next; //指向首元结点
while(anow!=NULL&&bnow!=NULL){ //当其中一个链表走到尽头时,跳出while
if(anow->exp==bnow->exp){ //指数相等,系数相加
anow->coef=anow->coef+bnow->coef;
anow=anow->next;
apre=apre->next;
bnow=bnow->next;
}else if(anow->exp<bnow->exp){ //结果链表a的指数小,那么直接保留anow
anow=anow->next;
apre=apre->next;
}else { //if(anow->exp>bnow->exp)
Poly bnew=new PNode;
bnew->exp=bnow->exp; //不能直接bnew=bnow吧!!!!!!
bnew->coef=bnow->coef;
/*将新结点插入anow之前,需要一个指向前驱结点的指针*/
bnew->next=anow;
apre->next=bnew;
apre=apre->next;
/*b链表的当前结点后移一位*/
bnow=bnow->next;
}
}
if(bnow!=NULL){ //说明走到头的是a链表,把b剩下的都加到a的后面去
apre->next=bnow;
}
}
int main(){
Poly heada,headb; //先给一个头指针
create(heada);
create(headb);
add(heada,headb);
Poly result=heada->next;
while(result!=NULL){ //输出结果
cout<<result->coef<<" "<<result->exp<<" ";
result=result->next;
}
return 0;
}
下面演示多项式7 + 3x + 9x^8 + 5x^17和8x + 2x^7 - 9x^8的加法
这一版的代码存在两个弊端。一是,当系数相加为0时,没有销毁这个结点,而是直接输出系数0(如上图输出了“0,8”);二是所有无用的结点我都没有销毁。下面给出优化版代码
四、优化版代码
在第一个if里加了如下四行代码可以解决第一个问题
if(anow->coef+bnow->coef==0){ //系数相加等于零,
apre->next=anow->next;
anow=apre->next;
bnow=bnow->next;
}
完整代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef struct PNode{
int exp; //指数
int coef; //系数
struct PNode *next; //指针域
}PNode,*Poly;
void create(Poly &p){
p=new PNode; //头指针指向头结点
p->next=NULL; //头结点指向空
Poly pre=p;
cout<<"请输入多项式的项数:"<<endl;
int n;
cin>>n;
for(int i=1;i<=n;i++){
Poly s=new PNode;
cin>>s->coef>>s->exp; //按照指数有小到大输入
s->next=NULL;
pre->next=s;
pre=s;
}
}
void add(Poly &a,Poly &b){ //把a当做存放结果的链表
Poly anow=a->next; //指向首元结点
Poly apre=a; //指向头结点
Poly bnow=b->next; //指向首元结点
while(anow!=NULL&&bnow!=NULL){ //当其中一个链表走到尽头时,跳出while
if(anow->exp==bnow->exp){ //指数相等,系数相加
if(anow->coef+bnow->coef==0){ //系数相加等于零,
apre->next=anow->next;
anow=apre->next;
bnow=bnow->next;
}else{
anow->coef=anow->coef+bnow->coef;
anow=anow->next;
apre=apre->next;
bnow=bnow->next;
}
}else if(anow->exp<bnow->exp){ //结果链表a的指数小,那么直接保留anow
anow=anow->next;
apre=apre->next;
}else { //if(anow->exp>bnow->exp)
Poly bnew=new PNode;
bnew->exp=bnow->exp; //不能直接bnew=bnow吧!!!!!!
bnew->coef=bnow->coef;
/*将新结点插入anow之前,需要一个指向前驱结点的指针*/
bnew->next=anow;
apre->next=bnew;
apre=apre->next;
/*b链表的当前结点后移一位*/
bnow=bnow->next;
}
}
if(bnow!=NULL){ //说明走到头的是a链表,把b剩下的都加到a的后面去
apre->next=bnow;
}
}
int main(){
Poly heada,headb; //先给一个头指针
create(heada);
create(headb);
add(heada,headb);
Poly result=heada->next;
while(result!=NULL){ //输出结果
cout<<result->coef<<" "<<result->exp<<" ";
result=result->next;
}
return 0;
}
五、如果像下面这样写
那么手画一下就知道,a和b变成同一条单链表了