您的位置:首页 > 理论基础 > 数据结构算法

使用链表实现两个多项式相加和相乘

2017-05-17 22:33 399 查看
设计函数分别求两个一元多项式的乘积与和。

输入格式:

输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。

输出格式:

输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出
0 0


输入样例:

4 3 4 -5 2  6 1  -2 0
3 5 20  -7 4  3 1

输出样例:

15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1
5 20 -4 4 -5 2 9 1 -2 0


要实现此程序,大概需要以下几个步骤:

1.读入多项式1

2.读入多项式2

3.进行加法计算

4.实现乘法计算

5.输出乘法计算结果

6.输出加法计算结果

1.考虑如何读入多项式

在这之前我们需要确定链表节点的结构

需要有coef存储一项多项式的系数

需要有expon存储一项多项式的指数

需要有link存储下一个节点的地址

故构造数据类型

typedef struct PolyNode * Polynomial;

struct PolyNode{

    int coef;

    int expon;

    Polynomial link;

};

在此数据结构基础上,构造一个链表,采用尾插法,因此需要一个尾指针,如果没有尾指针,每次在向链表中加入一个节点时,都需要从头遍历。

同时再考虑一个问题,在向链表结尾插入结点时,如果链表为空,则申请一个新节点插入当前位置,同时让尾指针指向该节点;

如果链表不为空,则需要申请一个节点插入当前位置的后面,所以在进行插入时需要判断是否为空。

为了统一操作,我们可以申请一个带头节点链表,这样在插入时每次都插入尾节点的后面,统一了操作,当然,在链表读入完成之后需要free掉头节点。

下面是插入节点Attach函数和读取多项式ReadPoly函数:

void Attach(int c, int e, Polynomial * rear)//插入节点操作
{
Polynomial input = (Polynomial)malloc(sizeof(struct PolyNode));
//申请新节点并赋初值
input->coef = c;
input->expon = e;
input->link = NULL;
(*rear)->link = input;
*rear = input; //修改末尾指针,因为是修改指针,故此处使用指针的指针
}
Polynomial ReadPoly()
{
Polynomial P1, rear, t;
int N;//多项式项数
int c,e;//用来暂存系数和指数
P1 = (Polynomial)malloc(sizeof(struct PolyNode));//申请头节点
//申请头节点是为了方便使用Attach函数时,不用区分rear是空还是非空,有了头节点都是非空,插入方便
P1->link = NULL;

rear = P1;//尾指针指向头节点
scanf("%d",&N);
while(N--)
{
scanf("%d %d",&c, &e);
Attach(c, e, &rear);
}
t = P1;
P1 = P1->link;
free(t);//头节点方便插入的使命完成,释放头节点
return P1;
}2.考虑如何进行多项式加法
首先传入两个多项式链表,申请一个链表存放相加的结果,依次取出两个多项式的节点

如果指数相等则相加,结果为零,释放该节点,不为零申请节点将加和结果存入节点,并将节点插入和多项式;

如果不相等,则把指数大的节点插入和多项式。

在一个链表计算完成之后若另一个链表还有节点,则将剩余节点全部插入和多项式

以下为加和函数:

Polynomial AddPoly(Polynomial P1, Polynomial P2)
{
Polynomial t1,t2,rear,t;
t1 = P1;
t2 = P2;
Polynomial P = (Polynomial)malloc(sizeof(struct PolyNode));
P->link = NULL;
rear = P;
while(t1 && t2)
{
if(t1->expon == t2->expon)//如果指数相同则进行相加
{
if(t1->coef + t2->coef)//如果系数相加不为零,则将计算结果加入P中
{
Attach(t1->coef + t2->coef, t1->expon, &rear);
}
t1 = t1->link;
t2 = t2->link;
}
else if(t1->expon > t2->expon)//找到指数大的加入到P中
{

Attach(t1->coef, t1->expon, &rear);
t1 = t1->link;
}
else
{
Attach(t2->coef, t2->expon, &rear);
t2 = t2->link;
}
}
while(t1)//如果t1还有多余节点,则继续加入
{
Attach(t1->coef, t1->expon, &rear);
t1 = t1->link;
}
while(t2)//如果t2还有多余节点,则继续加入
{
Attach(t2->coef, t2->expon, &rear);
t2 = t2->link;
}
t = P;
P = P->link;
free(t);//释放头节点
return P;
}
3.考虑如何进行多项式乘法

有两种方法进行乘法计算:

1.先拿第一个多项式的第一项乘以第二个多项式,生成一个多项式,将此生成的多项式作为基本,之后用第一个多项式的第二项依次乘以第二个多项式的每一项,每生成一项,将结果插入到之前生成的多项式中。(相当于插入项)

2.将第一个多项式的每一项与第二个多项式相乘,每次生成一个多项式,将这些多项式相加得结果。(相当于多个多项式加和)

此处采用第一种方法:

首先用第一个多项式的第一项乘以第二个多项式生成一个基本多项式,因为以后每生成一项要执行插入操作,而插入操作需要知道插入位置之前的节点,故每次判断

"尾指针->link"是否和得到的乘积项的关系:

先将尾指针移动指数到不大于乘积项指数的前一项

若“尾指针->link->指数”与乘积项指数相同,则进行加法操作,若为零,删除节点;否则修改节点。

否则就是“尾指针->link->指数” < 乘积项指数,那么将乘积项插入到尾指针之后。

以下为乘法函数:

Polynomial MultyPoly(Polynomial P1, Polynomial P2)
{
Polynomial P, t1, t2, t, rear;
int c, e;
P = (Polynomial)malloc(sizeof(struct PolyNode));
P->link = NULL;

t1 = P1;
t2 = P2;
rear = P;

if(!t1 || !t2)//如果有一个多项式为空,则乘法结果为空
return NULL;

while(t2)//先用P1的第一项乘以P2生成一个多项式用于插入
{
c = t1->coef * t2->coef;
e = t1->expon + t2->expon;
Attach(c, e, &rear);
t2 = t2->link;
}
t1 = t1->link;//t1指向第二项
while(t1)
{
t2 = P2;//将指针重新指向P2的开头
rear = P;//用作寻找合适的插入位置
while(t2)
{
c = t1->coef * t2->coef;
e = t1->expon + t2->expon;
while(rear->link && rear->link->expon > e)//将rear指向指数与e相等或比e小的节点之前一个位置
rear = rear->link;
if(rear->link && rear->link->expon == e)//如果rear不为空且rear之后的节点指数和e相等,则进行相加
{
if(c + rear->link->coef)//如果相加不为0
{
rear->link->coef += c;
rear = rear->link;
}
else//相加结果为0 ,删除rear之后的节点
{
t = rear->link;
rear->link = t->link;
free(t);
}
}
else //构造一个新节点插入到rear之后
{
t = (Polynomial)malloc(si
4000
zeof(struct PolyNode));
t->coef = c;
t->expon = e;
t->link = rear->link;
rear->link = t;
rear = rear->link;
}
t2 = t2->link;
}
t1 = t1->link;
}
t = P;
P = P->link;
free(t);//释放掉头节点
return P;
}

4.如何进行输出
输出比较容易:

void PrintPoly(Polynomial P)
{
int flag = 0;
if(!P)
{
printf("0 0\n");
return;
}
while(P)
{
if(!flag)
flag = 1;
else
printf(" ");
printf("%d %d",P->coef, P->expon);
P = P->link;
}
printf("\n");
}


最后给出完整代码:

#include "stdio.h"
#include "stdlib.h"
/*
1.首先要进行多项式的读入,构造函数ReadPoly()
2.进行多项式加法,构造函数AddPoly()
3.进行多项式乘法,构造函数MultyPoly()
4.进行多项式的输出,怕、PrintPoly()
*/
typedef struct PolyNode * Polynomial;
struct PolyNode{
int coef;
int expon;
Polynomial link;
};
void Attach(int c, int e, Polynomial * rear);//将新读入的系数和指数加到多项式的末尾
Polynomial ReadPoly();//读入多项式
Polynomial AddPoly(Polynomial P1, Polynomial P2);//计算两个多项式之和
Polynomial MultyPoly(Polynomial P1, Polynomial P2);//计算两个多项式积
void PrintPoly(Polynomial P);
int main()
{
Polynomial P1 = ReadPoly();
Polynomial P2 = ReadPoly();
Polynomial PA = AddPoly(P1, P2);
Polynomial PP = MultyPoly(P1, P2);
PrintPoly(PP);
PrintPoly(PA);
}
void Attach(int c, int e, Polynomial * rear)
{
Polynomial input = (Polynomial)malloc(sizeof(struct PolyNode));
//申请新节点并赋初值
input->coef = c;
input->expon = e;
input->link = NULL;
(*rear)->link = input;
*rear = input; //修改末尾指针,因为是修改指针,故此处使用指针的指针
}
Polynomial ReadPoly()
{
Polynomial P1, rear, t;
int N;//多项式项数
int c,e;//用来暂存系数和指数
P1 = (Polynomial)malloc(sizeof(struct PolyNode));//申请头节点
//申请头节点是为了方便使用Attach函数时,不用区分rear是空还是非空,有了头节点都是非空,插入方便
P1->link = NULL;

rear = P1;//尾指针指向头节点
scanf("%d",&N);
while(N--)
{
scanf("%d %d",&c, &e);
Attach(c, e, &rear);
}
t = P1;
P1 = P1->link;
free(t);//头节点方便插入的使命完成,释放头节点
return P1;
}
Polynomial AddPoly(Polynomial P1, Polynomial P2)
{
Polynomial t1,t2,rear,t;
t1 = P1;
t2 = P2;
Polynomial P = (Polynomial)malloc(sizeof(struct PolyNode));
P->link = NULL;
rear = P;
while(t1 && t2)
{
if(t1->expon == t2->expon)//如果指数相同则进行相加
{
if(t1->coef + t2->coef)//如果系数相加不为零,则将计算结果加入P中
{
Attach(t1->coef + t2->coef, t1->expon, &rear);
}
t1 = t1->link;
t2 = t2->link;
}
else if(t1->expon > t2->expon)//找到指数大的加入到P中
{

Attach(t1->coef, t1->expon, &rear);
t1 = t1->link;
}
else
{
Attach(t2->coef, t2->expon, &rear);
t2 = t2->link;
}
}
while(t1)//如果t1还有多余节点,则继续加入
{
Attach(t1->coef, t1->expon, &rear);
t1 = t1->link;
}
while(t2)//如果t2还有多余节点,则继续加入
{
Attach(t2->coef, t2->expon, &rear);
t2 = t2->link;
}
t = P;
P = P->link;
free(t);//释放头节点
return P;
}
Polynomial MultyPoly(Polynomial P1, Polynomial P2)
{
Polynomial P, t1, t2, t, rear;
int c, e;
P = (Polynomial)malloc(sizeof(struct PolyNode));
P->link = NULL;

t1 = P1;
t2 = P2;
rear = P;

if(!t1 || !t2)//如果有一个多项式为空,则乘法结果为空
return NULL;

while(t2)//先用P1的第一项乘以P2生成一个多项式用于插入
{
c = t1->coef * t2->coef;
e = t1->expon + t2->expon;
Attach(c, e, &rear);
t2 = t2->link;
}
t1 = t1->link;//t1指向第二项
while(t1)
{
t2 = P2;//将指针重新指向P2的开头
rear = P;//用作寻找合适的插入位置
while(t2)
{
c = t1->coef * t2->coef;
e = t1->expon + t2->expon;
while(rear->link && rear->link->expon > e)//将rear指向指数与e相等或比e小的节点之前一个位置
rear = rear->link;
if(rear->link && rear->link->expon == e)//如果rear不为空且rear之后的节点指数和e相等,则进行相加
{
if(c + rear->link->coef)//如果相加不为0
{
rear->link->coef += c;
rear = rear->link;
}
else//相加结果为0 ,删除rear之后的节点
{
t = rear->link;
rear->link = t->link;
free(t);
}
}
else //构造一个新节点插入到rear之后
{
t = (Polynomial)malloc(sizeof(struct PolyNode));
t->coef = c;
t->expon = e;
t->link = rear->link;
rear->link = t;
rear = rear->link;
}
t2 = t2->link;
}
t1 = t1->link;
}
t = P;
P = P->link;
free(t);//释放掉头节点
return P;
}
void PrintPoly(Polynomial P)
{
int flag = 0;
if(!P)
{
printf("0 0\n");
return;
}
while(P)
{
if(!flag)
flag = 1;
else
printf(" ");
printf("%d %d",P->coef, P->expon);
P = P->link;
}
printf("\n");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息