链表实现多项式的加法和乘法
poly.h
#ifndef POLYNOMIALCOMPUTE_POLY_H
#define POLYNOMIALCOMPUTE_POLY_H
struct PolyNode;
typedef struct PolyNode *Polynomial;
void Attach(int c, int e, Polynomial *pRear);
Polynomial PolyAdd(Polynomial P1, Polynomial P2);
Polynomial PolyMult(Polynomial P1, Polynomial P2);
Polynomial ReadPoly();
void PrintPoly(Polynomial P);
#endif //POLYNOMIALCOMPUTE_POLY_H
poly.c
#include "poly.h"
#include <malloc.h>
#include <stdlib.h>
#include <stdio.h>
struct PolyNode {
Polynomial link; // 指向下一个节点的位置
int expon; // 指数,英文是 exponent
int coef; // 系数,英文是 coefficient
};
// 新增一个节点
void Attach(int c, int e, Polynomial *pRear)
{
Polynomial P;
P = (Polynomial)malloc(sizeof(struct PolyNode)); // 分配空间
P->coef = c; // 对新节点赋值
P->expon = e;
P->link = NULL;
(*pRear)->link = P; // 尾节点指向P
*pRear = P; // 修改 pRear 值
}
int Compare(int Lhs, int Rhs)
{
return Lhs - Rhs;
}
// 加法操作
Polynomial PolyAdd(Polynomial P1, Polynomial P2)
{
Polynomial front, rear, temp;
int sum;
rear = (Polynomial)malloc(sizeof(struct PolyNode));
front = rear; // 由 front 记录结果多项式链表头节点
while (P1 && P2)
{ // 当两个多项式都有非零项待处理时
switch (Compare(P1->expon, P2->expon))
{
case 1:
Attach(P1->coef, P1->expon, &rear);
P1 = P1->link;
break;
case -1:
Attach(P2->coef, P2->expon, &rear);
P2 = P2->link;
break;
case 0:
sum = P1->coef + P2->coef;
if (sum) Attach(sum, P1->expon, &rear);
P1 = P1->link;
P2 = P2->link;
break;
}
}
// 将未处理完的另一个多项式的所有节点依次复制到结果多项式中去
for(; P1; P1 = P1->link) Attach(P1->coef, P1->expon, &rear);
for(; P2; P2 = P2->link) Attach(P2->coef, P2->expon, &rear);
rear->link = NULL;
temp = front;
front = front->link; // 令 front 指向结果多项式的第一个非零项
free(temp); // 释放临时空表头节点
return front;
}
// 多项式的乘法
Polynomial PolyMult(Polynomial P1, Polynomial P2)
{
Polynomial P, Rear, t1, t2, t;
int c, e;
if (!P1 || !P2) return NULL;
t1 = P1;
P = (Polynomial)malloc(sizeof(struct PolyNode));
P->link = NULL;
while (t1)
{
t2 = P2; // 每次循环之后要把 t2 归位到链表的开头
Rear = P; // 每一次循环都要重新初始化 Rear,使 Rear 的初始值指向链表头
while (t2)
{
c = t1->coef + t2->coef;
e = t1->expon + t2->expon;
while (Rear->link && Rear->link->expon > e) // 注意,这里和 e 作比较的是 Rear 的下一个节点中的值,这样下面的插入操作才解释得通
Rear = Rear->link;
if (Rear->link && Rear->link->expon == e) {
if (Rear->link->coef + c)
Rear->link->coef += c;
else { // 系数相加等于 0 的情况,要把该节点删掉
t = Rear->link;
Rear->link = t->link;
free(t);
}
} else { // 指数相加啊小于尾节点指数的情况,直接附加到结尾就成
t = (Polynomial)malloc(sizeof(struct PolyNode));
t->coef = c;
t->expon = e;
t->link = Rear->link;
Rear->link = t; // 直接将 t2 的值附加到
Rear = Rear->link;
}
t2 = t2->link; // 指针往后移动
}
t1 = t1->link;
}
t2 = P;
P = P->link;
free(t2); // 释放第一个没有存储数据得节点
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");
}
// 读入多项式
Polynomial ReadPoly()
{
Polynomial P, Rear, t;
int c, e, N;
scanf("%d", &N);
P = (Polynomial)malloc(sizeof(struct PolyNode)); // 链表头空姐点
P->link = NULL;
Rear = P; // 复制 P 到 Rear,这样就可以不修改 P
while (N--) {
scanf("%d %d", &c, &e);
Attach(c, e, &Rear); // 将当前项插入多项式尾部
}
t = P;
P = P->link;
free(t); // 删除临时生成头节点(因为里面也没存储数据)
return P;
}
main.c(测试函数)
#include "poly.h"
// 测试函数
int main()
{
Polynomial P1, P2, PP, PS; // PP 表示多项式乘积 Product,PS表示多项式和 Summary
P1 = ReadPoly();
P2 = ReadPoly();
PP = PolyMult(P1, P2);
PrintPoly(PP);
PS = PolyAdd(P1, P2);
PrintPoly(PS);
return 0;
}
测试样例输出: