C语言实现多项式相加与相乘

#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;
}

 输出结果:

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值