#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define INFEASIBLE -1
#define OVERFLOW -2
#define Status int
#define ERROR 0
typedef struct Nomial {
double coef; //系数
int expo; //指数
struct Nomial* next;
}Nomial, * pNomial;
typedef struct Polynomial {
pNomial firstNomial, tail; //首结点以及尾指针
}*Polynomial;
Status initialPolynomial(Polynomial* p) { //构思:结点按照指数从小到大排序
(*p) = (Polynomial)malloc(sizeof(struct Polynomial));
if (!(*p)) exit(OVERFLOW);
(*p)->firstNomial = (pNomial)malloc(sizeof(Nomial));
if(!(*p)->firstNomial) exit(OVERFLOW);
(*p)->firstNomial->coef = -999.999; //首结点系数无意义,随便填
(*p)->firstNomial->expo = 0; //首结点指数类型为int,记录链表有效结点长度,初始化为0
(*p)->firstNomial->next = NULL; //非循环链表
(*p)->tail = (*p)->firstNomial; //初始化尾指针
return OK;
}
int locateElementPolynomial(Polynomial p, int expo) { //用于定位指数为expo的结点在链表中的位置
if (p->firstNomial == p->tail) return -1; //空链表
pNomial ptr = p->firstNomial->next;
int res = 0;
while (ptr && ptr->expo < expo) {
ptr = ptr->next;
++res;
}
/* 分情况讨论:
* 1.ptr不存在跳出循环:expo很大,返回尾结点序号
* 2.ptr所指结点指数>=expo,返回ptr所指结点前一个结点的序号
*/
return res;
}
void insertPolynomial(Polynomial p, double coef, int expo) {
pNomial nomial = (pNomial)malloc(sizeof(Nomial));
if (!nomial) exit(OVERFLOW);
nomial->coef = coef; nomial->expo = expo; nomial->next = NULL;
int index = locateElementPolynomial(p, expo);
if (index == -1) { //空链表直接插入
p->tail->next = nomial;
p->tail = nomial;
++p->firstNomial->expo;
return;
}
pNomial ptr = p->firstNomial;
while (index--) ptr = ptr->next; //ptr指向插入位置前一个结点
if (ptr == p->tail) { //插入结点应为新尾指针
p->tail->next = nomial;
p->tail = nomial;
++p->firstNomial->expo;
return;
}
if (expo == ptr->next->expo) { //插入结点可并入已有结点
if (coef + ptr->next->coef) //新系数不为零
ptr->next->coef += coef;
else { //新系数为零,删除结点
pNomial tmp = ptr->next;
ptr->next = ptr->next->next;
--p->firstNomial->expo;
free(tmp);
}
}
else { //插入新结点
nomial->next = ptr->next;
ptr->next = nomial;
++p->firstNomial->expo;
}
}
void showPolynomial(const Polynomial p) { //可优化负系数项以及常数项,懒癌发作算了
if (p->firstNomial == p->tail) {
printf("EMPTY.\n");
return;
}
printf("Polynomial with %i nomials:\n ", p->firstNomial->expo);
pNomial ptr = p->firstNomial->next;
int i = 0;
while (ptr) {
printf("(%8.2f X^ %3i)", ptr->coef, ptr->expo);
if (ptr == p->tail) {
printf("\n");
return;
}
if (++i % 5) printf(" + ");
else printf("\n+ ");
ptr = ptr->next;
}
}
void addPolynomial(Polynomial res, const Polynomial addend) {
int i = addend->firstNomial->expo;
pNomial ptr = addend->firstNomial;
while (i--) {
ptr = ptr->next;
insertPolynomial(res, ptr->coef, ptr->expo);
}
}
void multiplyPolynomial(const Polynomial p1, const Polynomial p2, Polynomial res) {
pNomial ptr1 = p1->firstNomial->next;
for (int i = 0; i < p1->firstNomial->expo; ++i) {
pNomial ptr2 = p2->firstNomial->next;
for (int j = 0; j < p2->firstNomial->expo; ++j) {
insertPolynomial(res, ptr1->coef * ptr2->coef, ptr1->expo + ptr2->expo);
ptr2 = ptr2->next;
}
ptr1 = ptr1->next;
}
}
void destroyPolynomial(Polynomial p) {
pNomial ptr = p->firstNomial, tmp = NULL;
while (ptr) {
tmp = ptr->next;
free(ptr);
ptr = tmp;
}
free(p);
}
int main() {
Polynomial p1 = NULL, p2 = NULL, p3 = NULL;
initialPolynomial(&p1); initialPolynomial(&p2); initialPolynomial(&p3);
insertPolynomial(p1, 3, 2);
insertPolynomial(p1, 2, 0);
insertPolynomial(p2, 4, 4);
insertPolynomial(p2, 4, 0);
showPolynomial(p1); showPolynomial(p2);
multiplyPolynomial(p1, p2, p3);
showPolynomial(p3);
destroyPolynomial(p1); destroyPolynomial(p2); destroyPolynomial(p3);
return OK;
}
输出结果: