首先,我们先来分析一下,一元多项式相加,首先要用链表创建两个或多个多项式,每个节点里的数据有两个,系数和指数;其次,如果要实现乱幂输入,那么还需要一个排序函数;然后就是多项式相加求和的部分,当指数相等时其系数相加,如果不相等那么就比较大小,依次存入新的链表;最后是输出函数,这个部分也分了很多类型,比如:两式相加为常数(2,4,6)、0、系数为1不显示系数(x,x^4)、指数为1不显示指数(x,2x)等等。
先来定义结构体变量,和单链表的定义结构体一样,不同的是此时我们的数据变成了两个:系数和指数。所以我们这样定义:
typedef struct node{//构造结构体变量
int coefficient;//定义一个结构体变量“系数”
int exponent;//定义一个结构体变量“指数”
node *next;
}node;
然后创建单链表来存储第一个多项式的各项式:
node *create(){//尾插法创建单链表
node *head,*p,*q;
int n;//定义一个整型数据n,用来表示输入的多项式的个数
int i = 0;//定义一个整型数据i=0,用来表示的输入的第几个多项式的系数或指数
head = (node*)malloc(sizeof(node));//给head分配内存空间
head->next = NULL; //先让head为空表
q = head;//让q等于head的头节点
printf("你想要输入多少个多项式的数据:");
scanf("%d",&n);
for(i = 0;i < n;i++){
p = (node*)malloc(sizeof(node));//给p分配内存空间
printf("请输入第%d项的系数:",i+1);
scanf("%d",&p->coefficient);//输入系数
printf("请输入第%d项的指数:",i+1);
scanf("%d",&p->exponent);//输入指数
p->next = q->next;
q->next = p;
q = q->next;
}
return head;
}
输出函数,注意这个函数是将两个多项式相加的和已经求出来了进行输出,是把没必要的省略(比如结果为2x^0输出为2),大家看程序就懂了,我就不废话了。
void print(node *head){//输出单链表
node *p;
p = (node*)malloc(sizeof(node));
p = head->next;
while(p->next != NULL){//如果p的后继节点不为空时执行下列语句
if(p->coefficient != 0 && p->exponent == 0){//系数不为0指数为0的情况(常数)
printf("%d+",p->coefficient);//所以只输入系数
}
else if(p->coefficient == 1 && p->exponent == 1){//系数为1指数为1的情况
printf("x+");
}
else if(p->coefficient != 0 && p->exponent == 1){//系数不为0指数为1的情况(x,2x,5x……)
printf("%dx+",p->coefficient);//注意前面%d后的x
}
else if(p->coefficient == 1 && p->exponent != 0){//系数为1指数不为0的情况(x^2,x^5……)
printf("x^%d+",p->exponent);
}
else if(p->coefficient == 0){//两个多项式相加的和为0时的情况,不输出
printf("");
}
else if(p->coefficient != 1 && p->exponent != 0){//系数不为1指数不为0的情况(2x^3,3x^2……)
printf("%dx^%d+",p->coefficient,p->exponent);
}
p = p->next;//让p等于它的后继结点,继续循环
}
if(p->exponent == 0 && p->coefficient != 0){//判断最后一个多项式的类型 (ps:因为上述循环当中我们定义p->next!=NULL时执行,那么当p为最后一个结点时,p->next已经是空了,那么这个时候就会跳出循环,最后一个结点的数据就会不运行出来,所以我们需要另写,如果不想写这么多代码的话让它在循环内输出也很简单,大家可以动脑筋想一想),下列语句同上
printf("%d",p->coefficient);
}
else if(p->coefficient == 1 && p->exponent == 1){//系数为1指数为1的情况
printf("x+");
}
else if(p->exponent == 1 && p->coefficient != 0){
printf("%dx",p->coefficient);
}
else if(p->coefficient == 1 && p->exponent != 0){
printf("x^%d",p->exponent);
}
else if(p->coefficient == 0){
printf("0"); //这条语句和上面不一样,因为这是最后一个多项式的输出,如果最后一个多项式的计算结果为0,那么不这样写就会输出(……+)有一个加号,不美观
}
else if(p->coefficient != 1 && p->exponent != 0){
printf("%dx^%d",p->coefficient,p->exponent);
}
}
然后就是排序,注意这个排序是将还未执行求和函数的两个多项式进行升幂排序,然后进行相加。(不是已经求和之后进行升幂排序)
void paixu(node *head){//将多项式按升幂排序
node *p,*q;
int temp,temp1;
for(p=head->next;p!=NULL;p=p->next){//运用了两个for循环
for(q=p->next;q!=NULL;q=q->next){//q为p的后继结点
if(p->exponent > q->exponent){//如果p的指数比q的指数大,也就是前一项的指数比后一个指数大,那么交换它们的指数和系数
temp = p->exponent;
p->exponent = q->exponent;
q->exponent = temp;
temp1 = p->coefficient;
p->coefficient = q->coefficient;
q->coefficient = temp1;
}
}
}
}
最后是多项式相加
node *add(node *&head1,node *head2){//一元多项式相加 (将一元多项式相加的结果存放在head1中)
node *a,*b,*p;
a = head1->next;
b = head2->next;
p = head1;
while(a != NULL && b != NULL){
if(a->exponent == b->exponent){
a->coefficient = a->coefficient+b->coefficient;
p->next = a;
p = p->next;
a = a->next;
b = b->next;
}
else if(a->exponent < b->exponent){
p->next = a;
p = p->next;
a = a->next;
}
else{
p->next = b;
p = p->next;
b = b->next;
}
}
if(a != NULL){//比较结束之后a或b如果有一个还未空就执行下述语句
p->next = a;
}
else{
p->next = b;
}
return head1;
}
最后主函数
int main(){
node *head1,*head2,*h;
head1 = create();//创建第一个多项式
head2 = create();//创建第二个多项式
paixu(head1);//将第一个多项式按升幂排序
paixu(head2);//同上
h = add(head1,head2);//相加
print(h);//输出
return 0;
}
然后一个多项式相加的代码就完成了,在写博客的过程中突然发现自己相加和输出函数有一些问题,就顺便改正了,不得不说这写博客真的好处多多啊,还有就是输出函数里的分类没有完整,因为有系数为负数的情况,我懒得写了,大家有兴趣的可以写一写,不难的,就是简单的判断语句。
哦!还缺一个头文件
#include<stdio.h>
#include<stdlib.h>
这就完美了。
最后奉上一个运行结果
这是vscode的运行结果
上述程序依次写入Dev-C++和vscode以及vs2019中都可以执行,但如果是vs2019里其scanf要改为scanf_s,因为这是vs2019的编译规则。
最后,就希望路过的大佬可以给一点建议,还有就是希望和我一样的编程小白可以一起努力!