假设指针qa和qb分别指向多项式A和多项式B中当前比较的某个结点,那么和多项式运算总共有三种情况出现:
1、指针qa所指结点的指数值 < 指针qb所指结点的指数值,则需摘取qa指针所指结点插入到“和多项式”链表中去;
2、指针qa所指结点的指数值 > 指针qb所指结点的指数值,则需摘取qb指针所指结点插入到“和多项式”链表中去;
3、指针qa所指结点的指数值 = 指针qb所指结点的指数值,则将两个结点中的系数相加,若和数不为零,则修改qa所指结点的系数值,同时释放qb所指结点;反之,从多项式A的链表中删除相应的结点,并释放指针qa和qb所指结点。
#include <iostream>
#include <cstdio>
using namespace std;
struct Node {
double coef;
int expn;
Node *next;
};
void CreatPolynomial(Node *&head, int n) // 生成带表头结点的单链表,除头结点外另生成n个结点
{
head = (Node *)malloc(sizeof(Node));
head->coef = 0;
head->expn = 0;
head->next = NULL; // 初始化头结点
cout << "请输入各项系数及指数:" << endl;
Node *p = head;
for (int i = 0; i < n; i++) {
p->next = (Node *)malloc(sizeof(Node)); // 生成新结点,尾插入生成链表
p = p->next;
cin >> p->coef >> p->expn;
p->next = NULL;
}
}
void PrintPolynomial(Node *&head)
{
if (head->next == NULL) // 结果是0时直接输出0
putchar('0');
else {
for (Node *p = head->next; p != NULL; p = p->next) {
if (p != head->next && p->coef >0) // 当p非首项且指向的系数为正时才输出'+'
putchar('+'); // 之前只判定了p->coef >0
if (p->coef == 1) { // 系数为1或-1时特殊处理
if (p->expn == 0)
putchar('1'); // 判断条件不能写在一起:
} // if(p->coef == 1 && p->expn == 0) putchar('1');
else if (p->coef == -1)
putchar('-');
else
cout << p->coef;
switch (p->expn) { // 指数为0或1时特殊处理
case 0:
break;
case 1:
putchar('x');
break;
default:
p->expn < 0 ? printf("x^(%d)", p->expn) : printf("x^%d", p->expn); // 指数小于0时打括号
break;
}
}
}
cout << endl;
}
// 上面的函数中若系数为int型,那么也可以改为switch结构,这是C语言的缺陷?
void Free(Node *&head)
{
Node *q = NULL;
for (Node *p = head; p != NULL; p = q) {
q = p->next;
free(p);
}
}
char cmp(int a, int b)
{
if (a > b)
return '>';
if (a < b)
return '<';
return '=';
}
void AddPolynomial(Node *&pA, Node *&pB) // 传进两个链表的头指针
{
Node *ha = pA;
Node *hb = pB;
Node *qa = ha->next; // ha, hb分别跟在qa, qb的后一位置
Node *qb = hb->next; // qa, qb分别指向Pa, Pb中当前比较元素
while (qa && qb)
{
double sum = 0;
int a = qa->expn;
int b = qb->expn;
switch (cmp(a, b)) {
case '<':
ha = qa;
qa = qa->next; // 非ha = ha->next;
break;
case '=':
sum = qa->coef + qb->coef;
if (sum != 0.0) {
qa->coef = sum;
ha = qa;
}
else {
if (ha->next != qa)
cout << "Error: ha->next != qa" << endl;
ha->next = ha->next->next; // 删除和为0的结点,ha不变,还在qa后一位置
free(qa);
}
if (hb->next != qb)
cout << "Error: hb->next != qb" << endl;
hb->next = hb->next->next;
free(qb);
qb = hb->next;
qa = ha->next;
break;
case '>':
hb->next = hb->next->next; // 删除qb指向的结点
qb->next = ha->next; // 将qb插入ha后qa前
ha->next = qb;
qb = hb->next; // not qb = ha->next
ha = ha->next;
break;
default:
cout << "Error!" << endl;
break;
}
}
if (qb)
ha->next = qb;
free(hb);
}
int main(void)
{
// freopen("cin.txt", "r", stdin);
Node *A = NULL;
Node *B = NULL;
int lenA;
int lenB;
while (cout << "请输入A的项数:" << endl, cin >> lenA) {
CreatPolynomial(A, lenA); // 生成A链表
cout << "请输入B的项数:" << endl; // 生成B链表
cin >> lenB;
CreatPolynomial(B, lenB);
cout << " A = "; // 输出A链表
PrintPolynomial(A);
cout << " B = "; // 输出B链表
PrintPolynomial(B);
AddPolynomial(A, B); // A = A + B
cout << "A+B= ";
PrintPolynomial(A); // 输出和
cout << endl;
Free(A); // 务必释放结点
}
return 0;
}
注意输入各自多项式应当按照指数值递增输入