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

2023-10-27

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

如下图:

我们使用链表来模拟单元多项式的常见运算。其中,加法是其它运算的基础,减法: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()方法就可明白。

运行:



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


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


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


专栏完整目录:




本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 字符串09--表示数值的字符串

    字符串09 表示数值的字符串 jz53 题目概述 解析 参考答案 注意事项 说明 题目概述 算法说明 请实现一个函数用来判断字符串是否表示数值 包括整数和小数 例如 字符串 100 5e2 123 3 1416 和 1E 16 都表示数值
  • 对于单向链表的排序与去重

    include bits stdc h using namespace std struct node int num node next class Chain public Chain head tail new node void G
  • 2-数据结构-线性表之顺序表的动态分配

    说明 由于原来顺序表的静态分配 浪费空间 且存在溢出现象 因此采取动态分配的方式 创建顺序表中的数组 跟C语言正常动态分配一样 需要直到扩充的大小 和数组指针即可 代码如下 看着多 其实原理差不多 主要知道哪些操作即可 无需了解具体代码 i
  • 【数据结构】单向链表的修改和删除

    单向链表的修改和删除 从单链表中删除一个节点思路 1 找到需要删除节点的前一个节点temp 2 temp next temp next next 3 被删除的节点 将不会有其他引用指向 会被垃圾处理机制回收 1 单向链表的修改操作 1 1
  • 数据结构——计算节点个数和二叉树高度(C语言版)

    摘自 数据结构 计算节点个数和二叉树高度 C语言版 作者 正弦定理 发布时间 2020 12 12 23 27 09 网址 https blog csdn net chinesekobe article details 111086664
  • 讲解+可执行完整代码 C++单链表(2)查找、插入、删除元素

    目录 一 查找元素 代码部分 核心代码 完整代码 二 插入元素 核心思路 代码部分 核心代码 完整代码 编辑 三 删除元素 核心思路 代码部分 核心代码 完整代码 一 查找元素 此段代码仅实现查找元素的功能 代码部分 核心代码 node l
  • 双向链表详解

    目录 一 双向链表的概念及结构 二 双向链表的方法及其实现 2 1 双向链表 2 2 addFirst int data 头插法 2 3 addLast int data 尾插法 2 4 size 链表长度 2 5 display 打印链表
  • 机器学习算法GBDT的面试要点总结-上篇

    1 简介 gbdt全称梯度提升决策树 在传统机器学习算法里面是对真实分布拟合的最好的几种算法之一 在前几年深度学习还没有大行其道之前 gbdt在各种竞赛是大放异彩 原因大概有几个 一是效果确实挺不错 二是即可以用于分类也可以用于回归 三是可
  • 区块链中的哈希算法

    区块链中的密码学 密码学在区块链中的应用主要有两个 哈希算法与非对称加密算法 这次主要对哈希算法进行详细的说明 哈希算法 哈希算法的特点有 1 输入可以为任意大小的字符串 2 产生固定大小的输出 3 可以在合理的时间内算出输出值 若要满足密
  • 基数排序代码实现

    详情请看排序总结 传送门 https blog csdn net m0 52711790 article details 121914543 基数排序的知识点我就不贴出来 相信都能搜到对应概念解释 下面就直接上代码 代码解释其实也很清晰了
  • 用两个栈实现队列

    目录 一 栈的基本结构及其接口 二 我的队列结构定义 三 我的队列创建及其初始化 四 我的队列入队 五 我的队列出队 六 我的队列取队头元素 七 我的队列判空 八 我的队列销毁 一 栈的基本结构及其接口 栈的结构定义 typedef int
  • 算法题-简单系列-01-链表反转

    文章目录 1 题目 1 1 使用栈解决 1 2 反转链表 1 题目 给定一个单链表的头结点pHead 该头节点是有值的 比如在下图 它的val是1 长度为n 反转该链表后 返回新链表的表头 如当输入链表 1 2 3 时 经反转后 原链表变为
  • Leetcode1094. 拼车

    Every day a Leetcode 题目来源 1094 拼车 解法1 差分数组 对于本题 设 a i 表示车行驶到位置 i 时车上的人数 我们需要判断是否所有 a i 都不超过 capacity trips i 相当于把 a 中下标从
  • 【数据结构】单链表的定义和操作

    目录 1 单链表的定义 2 单链表的创建和初始化 3 单链表的插入节点操作 4 单链表的删除节点操作 5 单链表的查找节点操作 6 单链表的更新节点操作 7 完整代码 嗨 我是 Filotimo 很高兴与大家相识 希望我的博客能对你有所帮助
  • 剑指 Offer(第2版)面试题 35:复杂链表的复制

    剑指 Offer 第2版 面试题 35 复杂链表的复制 剑指 Offer 第2版 面试题 35 复杂链表的复制 解法1 模拟 剑指 Offer 第2版 面试题 35 复杂链表的复制 题目来源 48 复杂链表的复刻 解法1 模拟 算法 复制原
  • 华为OD机试 C++【最大载货量】

    描述 在火车站旁的货运站 小明负责调度2K辆中转车 其中K辆用于干货 K辆用于湿货 每批到站的货物来自不同的供货商 需要按照顺序装入中转车 注意 一个供货商的货物只能装在一辆车上 不能分开 但是 一辆车可以放多个供货商的货物 问题是 要让所
  • 排序:计数排序

    一 概念 计数排序是非比较排序 是对哈希直接定址法的变形应用 二 思想 利用数组统计相同数据出现的次数 例如整型数据m出现n次 就在数组m位置记录数据为n 最后从头遍历数组打印数据即可 通俗来讲就是 数组下标即为数据 下标所指位置的值即为数
  • 206.翻转链表

    翻转链表 力扣 LeetCode 官网 全球极客挚爱的技术成长平台 备战技术面试 力扣提供海量技术面试资源 帮助你高效提升编程技能 轻松拿下世界 IT 名企 Dream Offer https leetcode cn problems re
  • 单向不带头链表的使用

    单向不带头链表的使用 链表的创建 typedef struct LNode SLDataType data struct LNode next LNode LinkList 按位查找 LNode GetElem LinkList L int
  • 最大流-Dinic算法,原理详解,四大优化,详细代码

    文章目录 零 前言 一 概念回顾 可略过 1 1流网络 1 2流 1 3最大流 1 4残留网络 1 5增广路

随机推荐

  • 解决VScode使用git报错:Git: Bad status code: 500

    VS CODE GIT 500 问题处理 pudn com相关错误的处理链接博客 作为记录
  • C++ STL各标准容器使用手册

    原文 http blog csdn net nohackcc article details 8900017 1 vector 内部实现 数组 就是没有固定大小的数组 vector直接翻译是向量的意思 支持操作 begin 取首个元素 返回
  • 第10课 微信小程序数据存储(同步缓存、异步缓存,本地读取缓存):

    第10课 微信小程序数据存储 同 异步缓存 本地读取缓存 同步缓存 wx setStorageSync key value 异步缓存 wx setStorage Object object 同步删除缓存 wx removeStorageSy
  • java开发:java多线程(三):lock方式实现线程同步机制

    java多线程系列文章 java多线程 一 synchronized 对象锁和类锁的区别 java多线程 二 wait sleep join 和yield 区别 这章博客讲解lock如何实现同步机制 比较和synchronized 的区别
  • unity项目过程中本菜新遇到的问题和解决方案

    试出了奇怪的效果 还挺好看 canvas background text 在unity中打开的vs编辑器中没有代码提示 流星曳尾 博客园 这里我一开始不知道为啥text显示不出来 调成screen size才发现 是canvas方向反了 调
  • C语言-01

    以下内容为个人笔记 无实际参考意义 取地址符 int a 9 int pa 9 定义了一个今天类型的变量a 给他的值为9 定义了一个int类型的指针pa 指向变量a的地址 指定a输出的结果为9 指定 a输出的结果为存放a变量的地址 指定pa
  • linux如何做到不丢日志,rsyslogd日志丢失的解决

    最近发现跑keepalived的几台机器的日志总是打印不完 还好给抛了一个报错 信息如下 root yw lvs2 backup etc tail n 1000000 var log messages 20130526 grep rate
  • c语言中如何实现生成随机数

    文章目录 一 rand 函数 二 rand srand 三 rand sranf time 一 rand 函数 c语言中自带的生成随机数的函数rand 只要引用头文件 include
  • Apache Kafka Connect JNDI注入漏洞 (CVE-2023-25194) 安全风险通告

    https mp weixin qq com s biz MzU5NDgxODU1MQ mid 2247497666 idx 1 sn b58717baf54fe52ec517b89fe370f589 chksm fe79d35ac90e5
  • 自动化测试用例要怎么写,据说这是最全的......

    前言 自动化测试是使用专门的软件工具来验证软件解决方案 这通常涉及自动化功能作为测试过程的一部分 测试自动化最常见的对象是 测试管理和缺陷管理 单元和单元集成测试 功能测试 回归测试 非功能测试 如性能和可扩展性 自动化测试用例的编写是实现
  • 学习日记——《MQTT-JX》例程讲解(完结版)

    头文件 include ets sys h include driver uart h include osapi h include mqtt h include wifi h include config h include debug
  • 程序员思维方式

    今天去设备部修电脑的时候 看到他们部门在讨论个商业题目 看他们的津津有味 如痴如醉 吊起了我的无限兴趣 临走时让那妹子给我发了份邮件 回去好好研究研究 现将题目共享出来 和大家一起讨论讨论 据说这是一道可以测出一个人有没有商业头脑的数学题
  • NetCore连接MySQL

    打开VS 工具 NuGet包管理器 管理解决方案的NuGet程序包 搜索MySql Data并安装 测试连接MySQL的代码 using System using System Collections Generic using Syste
  • vue使用qrcode

    借鉴 vue中使用qrcode 生成二维码 有蝉的博客 CSDN博客 qrcode vue一 安装qrcode jsnpm install save qrcode二 封装生成二维码的组件index vue
  • 如何理解递归

    基本思想 写好递归要掌握几个技巧 1 明确递归函数的作用 将递归函数看作一个黑盒 我自己把该技巧称为黑盒思想 我认为黑盒思想对于理解递归有很大的作用 递归函数就是隐藏了很多细节 我们没必要去一步一步地模拟递归函数的运行 那样大脑也受不了 比
  • python:如何删除符合条件的图片

    import os import Image fileName fp open fileName rb im Image open fp fp close x y im size if x lt 300 or y lt 300 os rem
  • 自主设计,模拟实现 RabbitMQ - 多虚拟主机管理

    目录 前言 一 多虚拟主机管理 1 1 需求分析 1 1 1 回顾 1 1 2 实现方案 1 2 具体实现 lt
  • 学习 stm32 FATFS文件系统基础知识与示例应用

    文件系统 负责管理和存储文件信息的软件机构称为文件管理系统 简称文件系统 即在磁盘上组织文件的方法 理解 包含了对介质存储器进行地址 内容 读取操作的一些封装的功能API方便应用层直接使用 常用的文件系统 FAT FATFS NTFS 基于
  • 三色标记清除法

    文章目录 1 三色标记算法的概述 2 三色标记的过程 3 存在问题 3 1 错标 3 2 漏标 4 解决错杀问题 4 1 CMS 写屏障 增量更新 Incremental Update 4 2 G1 写屏障 原始快照 STAB 1 三色标记
  • 链表的应用:单元多项式的加法、减法、乘法

    使用链表来实现单元多项式的加法 减法 乘法 一个单元多项式的节点结构无非是这样的 系数域 指数域 链域 如下图 我们使用链表来模拟单元多项式的常见运算 其中 加法是其它运算的基础 减法 poly1 poly2 poly1 poly2 乘法