链表的应用:单元多项式的加法、减法、乘法

使用链表来实现单元多项式的加法、减法、乘法。一个单元多项式的节点结构无非是这样的:系数域、指数域、链域。

如下图:

我们使用链表来模拟单元多项式的常见运算。其中,加法是其它运算的基础,减法:poly1-poly2=poly1+(-poly2),乘法:poly1*poly2,可用poly1乘以poly2的每一项,相加其乘积结果。

单元多项式的节点结构类型是这样的:

typedef struct node
{
	float coef;   //系数
	int expn;     //指数
	struct node *next;
}PolyNode;      //多项式节点 polynomial node 

多项式的加法我们提供了两种:

1.Polynomial polyAdd(Polynomial poly1, Polynomial poly2),把poly1和poly2相加得到一个新的多项式,相加的过程中poly1和poly2保持不变,不会被破坏。

2.void add(Polynomial poly1, Polynomial poly2),把poly2加到poly1上,相加的过程中poly2的节点会被利用上。结束后,poly2不存在了。

提供第一种加法,是为了保持poly1和poly2不变,以便进行下一次的运算。提供第二种加法,是为了运算结束后,内存不会泄露。

其它具体细节得看代码了:

#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
	float coef;   //系数
	int expn;     //指数
	struct node *next;
}PolyNode;      //多项式节点 polynomial node
typedef PolyNode* Polynomial;
Polynomial createPolynomial()   //创建多项式
{
	PolyNode *p, *q, *head = (PolyNode *)malloc(sizeof(PolyNode));   //头节点
	head->next = NULL;
	float coef;
	int expn;
	printf("输入该多项式每一项的系数和指数,每项一行,输入0 0结束!\n");
	while (scanf("%f %d", &coef, &expn) && coef)    // 默认,按指数递减排列
	{
		if (head->next)
		{
			p = head;
			while (p->next && expn < p->next->expn)
				p = p->next;
			if (p->next)
			{
				if (expn == p->next->expn)  //有相同指数的直接把系数加到原多项式
				{
					p->next->coef += coef;
					//若是相加后系数为0,则舍弃该节点
					if (p->next->coef > -0.000001 && p->next->coef < 0.000001)
					{
						q = p->next;
						p->next = q->next;
						free(q);
					}
				}
				else
				{
					q = (PolyNode*)malloc(sizeof(PolyNode));
					q->coef = coef;
					q->expn = expn;
					q->next = p->next;
					p->next = q;
				}
			}
			else
			{
				p->next = (PolyNode*)malloc(sizeof(PolyNode));
				p = p->next;
				p->coef = coef;
				p->expn = expn;
				p->next = NULL;
			}
		}
		else
		{
			head->next = (PolyNode*)malloc(sizeof(PolyNode));
			head->next->coef = coef;
			head->next->expn = expn;
			head->next->next = NULL;
		}
	}
	return head;
}
//多项式与指定单项式相乘,该单项式为 coefx^expn
Polynomial multiply(Polynomial poly, float coef, int expn)
{
	PolyNode *p, *q, *Poly = (PolyNode*)malloc(sizeof(PolyNode));
	p = Poly;
	q = poly->next;
	while (q)
	{
		p->next = (PolyNode*)malloc(sizeof(PolyNode));
		p = p->next;
		p->coef = (q->coef*coef);
		p->expn = (q->expn + expn);
		q = q->next;
	}
	p->next = NULL;
	return Poly;
}
void add(Polynomial poly1, Polynomial poly2)   //把 poly2 加到 poly1 上
{
	PolyNode *p, *q, *r;
	r = poly1;
	p = poly1->next;  //指向第一个节点
	q = poly2->next;
	poly2->next = NULL;
	while (p && q)
	{
		if (p->expn > q->expn)
		{
			r->next = p;
			p = p->next;
			r = r->next;
		}
		else if (p->expn < q->expn)
		{
			r->next = q;
			q = q->next;
			r = r->next;
		}
		else
		{
			PolyNode *t;
			p->coef += q->coef;
			if (!(p->coef > -0.000001 && p->coef < 0.000001)) //系数不为0
			{
				r->next = p;
				r = r->next;
				p = p->next;
			}
			else
			{
				t = p;
				p = p->next;
				free(t);
			}
			t = q;
			q = q->next;
			free(t);
		}
	}
	if (p)
		r->next = p;
	if (q)
		r->next = q;
}
//多项式减法 poly1-poly2形成一个新的多项式
Polynomial polySubtract(Polynomial poly1, Polynomial poly2)
{
	//把poly2的系数取相反数,形成一个新的多项式
	Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode)); //构造头节点
	PolyNode *p, *q;
	p = poly;
	q = poly2->next;
	while (q)
	{
		p->next = (PolyNode*)malloc(sizeof(PolyNode));
		p = p->next;
		p->coef = -(q->coef);  //系数取反
		p->expn = q->expn;
		q = q->next;
	}
	p->next = NULL;
	add(poly, poly1);  //利用加法
	return poly;
}
//多项式相加 poly1+poly2形成一个新的多项式
Polynomial polyAdd(Polynomial poly1, Polynomial poly2)
{
	Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode));  //和多项式的头节点
	poly->next = NULL;
	PolyNode *p, *q, *r;
	r = poly;
	p = poly1->next;
	q = poly2->next;
	while (p&&q)
	{
		if (p->expn > q->expn)
		{
			r->next = (PolyNode*)malloc(sizeof(PolyNode));
			r = r->next;
			r->coef = p->coef;
			r->expn = p->expn;
			p = p->next;
		}
		else if (p->expn < q->expn)
		{
			r->next = (PolyNode*)malloc(sizeof(PolyNode));
			r = r->next;
			r->coef = q->coef;
			r->expn = q->expn;
			q = q->next;
		}
		else
		{
			float m = p->coef + q->coef;
			if (!(m > -0.000001 && m < 0.000001))
			{
				r->next = (PolyNode*)malloc(sizeof(PolyNode));
				r = r->next;
				r->coef = m;
				r->expn = p->expn;
			}
			q = q->next;
			p = p->next;
		}
	}
	while (p)
	{
		r->next = (PolyNode*)malloc(sizeof(PolyNode));
		r = r->next;
		r->coef = p->coef;
		r->expn = p->expn;
		p = p->next;
	}
	while (q)
	{
		r->next = (PolyNode*)malloc(sizeof(PolyNode));
		r = r->next;
		r->coef = q->coef;
		r->expn = q->expn;
		q = q->next;
	}
	r->next = NULL;
	return poly;
}
Polynomial polyMultiply(Polynomial poly1, Polynomial poly2)   //多项式相乘
{
	Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode));  //创建多项式和的头节点
	poly->next = NULL;
	PolyNode *p;
	p = poly2->next;
	while (p)
	{
		add(poly, multiply(poly1, p->coef, p->expn));
		p = p->next;
	}
	return poly;
}
void printPoly(Polynomial poly)    //打印多项式
{
	if (poly && poly->next)
	{
		PolyNode *p = poly->next;  //p指向第一个节点
		while (p->next)
		{
			printf("%gx^%d", p->coef, p->expn);
			p = p->next;
			if (p && (p->coef > 0))
				printf("+");
		}
		if (p->expn == 0)
			printf("%g", p->coef);   //打印常数项
		else
			printf("%gx^%d", p->coef, p->expn);
		printf("\n");
	}
}
void clear(Polynomial poly)   //释放内存
{
	if (poly && poly->next)
	{
		PolyNode *p, *q;
		p = poly;
		while (p)
		{
			q = p->next;
			free(p);
			p = q;
		}
	}
	poly = NULL;
}

调用方法:

int main()
{
	printf("用链表实现多项式的加减法\n");
	Polynomial poly1, poly2, poly;
	printf("创建多项式一\n");
	poly1 = createPolynomial();
	printf("多项式一:\n");
	printPoly(poly1);
	printf("创建多项式二\n");
	poly2 = createPolynomial();
	printf("多项式二:\n");
	printPoly(poly2);
	printf("两多项式相加,和为:\n");
	poly = polyAdd(poly1, poly2);
	printPoly(poly);
	clear(poly);
	printf("两个多项式相乘,积为:\n");
	poly = polyMultiply(poly1, poly2);
	printPoly(poly);
	clear(poly);
	printf("两多项式相减,差为:\n");
	poly = polySubtract(poly1, poly2);
	printPoly(poly);
	clear(poly1);
	clear(poly2);
	clear(poly);
	system("pause");
	return 0;
}

调用中,调用次序是加法、乘法、减法,减法放最后。这是因为减法的过程中poly2会别破坏掉。仔细看看add()方法就可明白。

运行:

代码比较长,逻辑有些复杂,得反复地看。

完整代码下载:一元多项式的加法、减法、乘法

若是有所帮助,顶一个哦!

专栏完整目录:数据结构与算法目录

链表的应用:单元多项式的加法、减法、乘法,布布扣,bubuko.com

时间: 2024-12-16 03:01:40

链表的应用:单元多项式的加法、减法、乘法的相关文章

BigDecimal 加法减法乘法除法

Java的简单类型不能够精确的对浮点数进行运算 /** * 提供精确的加法运算. * @param v1 被加数 * @param v2 加数 * @return 两个参数的和 */ public static double add(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); ret

数据结构第二次上机实验【链表实现多项式的加法和乘法】

利用链表实现一元多项式的加法和乘法 #define null 0 #include "stdio.h" #include "stdlib.h" #include "math.h" int op; typedef struct { float coef;//系数 int expn;//指数 }term; typedef struct Lnode { term data; Lnode *next; }*Link,*Linklist; int cmp(

加法 减法 乘法 除法计算

加法: function numAdd(num1, num2) {  var baseNum, baseNum1, baseNum2;  try {   baseNum1 = num1.toString().split(".")[1].length;  } catch (e) {   baseNum1 = 0;  }  try {   baseNum2 = num2.toString().split(".")[1].length;  } catch (e) {   

高精度 加法 减法 乘法 除法 整合

此文为博主原创,转载时请通知博主,并把原文链接放在正文醒目位置. 很久不写高精了,虽说我觉得高精也不会考...还是稍微写一写,防止手生. 两个小时过去了…… 集合了高精+高精.高精-高精.高精*高精.高精/低精. 目前还没发现什么错误,应该可以应付各种情况. 本来想允许它读入负数的,结果发现减法读负数太麻烦了...所以只能读非负数. 下面贴代码. 1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 #

数据结构之利用单向链表实现多项式加法和乘法

在<数据结构与算法分析--c语言描述>一书中,作者指出了使用单向链表作为实现多项式的方法.但是没有给出具体实现.下面自己对其进行实现.只考虑功能.对其他细节不暂时不考虑.程序完成两个功能,使用单向链表完成多项式的加法和乘法.首先看加法,解决加法问题的思想在于对表示进行操作的两个链表表示的多项式按照指数递减的结构排列,每个节点的数据域存储着多项式某一项的系数(Coefficient)和指数(Exponent),还有一个指向后继节点的指针.节点的实现如下: 1 typedef struct Nod

[DataStructure]多项式加法与乘法--B.链表存储(适用于零元系数多的多项式)

数据结构大作业…… 发出来大家乐呵乐呵…… 一.问题描述 给出N个多项式,求他们的和与积 二.解题报告 基本思想:加法和乘法都是把得数项直接链接在链表后面,最后统一做一个Merge&Sort工作即可.方便又快捷. (1)建立存储结构 1 struct _Poly 2 { 3 int factor;//系数 4 int Index;//幂 5 struct _Poly* next;//下一节点 6 }; 7 _Poly* poly[MAXTIMES+1]; 8 int Sum[MAXTIMES+1

[DataStructure]多项式加法与乘法--A.数组存储(适用于零元系数少的多项式)

数据结构大作业…… 发出来大家乐呵乐呵…… 一.问题描述 给出N个多项式,求他们的和与积 二.解题报告 (1)建立存储结构 1 struct _Poly 2 { 3 double Data[MAXTIMES+1]; 4 int Times; 5 }; 6 struct _Poly Poly[N+1]; (2)主程序架构 1 int main() 2 { 3 int Sum; 4 cout<<"请输入要做运算的多项式数量"<<endl; 5 cin>>

实现多项式的加法和乘法运算

不知道为啥,自己编程运行可以,一到PTA上运行就报错.不过算应该是没错的 1 #include<stdio.h> 2 #include<stdlib.h> 3 /*使用链表实习多项式的加法运算*/ 4 typedef struct linkList{ 5 int xiShu; 6 int ciShu; 7 struct linkList *next; 8 }list,*pList; 9 10 11 pList init_linkList(){ 12 pList head; 13 h

LeetCode:Add Two Numbers - 两个链表逐项做带进位的加法生成新链表

1.题目名称 Add Two Numbers (两个链表逐项做带进位的加法生成新链表) 2.题目地址 https://leetcode.com/problems/add-two-numbers/ 3.题目内容 英文:You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a