【链表实现】一元多项式相加相乘【详解相加相乘】

目录

一、一元多项式的表示

1、概念

2、用什么数据结构实现?

二、一元多项式的实现

1、基本结构概况

2、创建一元多项式

3、节点的尾插

4、一元多项式相加

5、一元多项式相乘

6、多项式的打印

 7、 Poly的析构函数

8、完整代码

Poly.h:

Poly.cpp 

test.cpp

9、运行测试

三、艰难的调试过程(可不看,我自己看的)


一、一元多项式的表示

1、概念

形如:Pn(x) = P0 + P1x + p2X^2 + ...... + Pnx^n就叫n阶多项式

n阶多项式Pn(x)有 n+1 项

  • 系数:P0,P1,P2,......Pn
  • 指数:0,1,2,......,n,按升幂排列

2、用什么数据结构实现?

可见用顺序表存储会很浪费空间,故用链表来存储

优点

  • 多项式的项数可以动态的增长,不存在存储溢出问题
  • 插入、删除方便,不移动数据

二、一元多项式的实现

分三个文件实现

Poly.h    Poly.cpp    test.cpp

1、基本结构概况

//链表的多项式节点
struct Polynode
{
	int _coef;//系数
	int _exp;//指数
	struct Polynode* _next;

	Polynode(int coef = 0,int exp = 0)
		:_next(nullptr)
		,_coef(coef)
		,_exp(exp)
	{}

	~Polynode()
	{
		_next = nullptr;
	}
};

//一元多项式
class Poly
{
public:
	void CreatePoly();//创建
	void Print();//打印
	void Push_back(Polynode* node);//尾插
	void AddPoly(Poly& p2, Poly& sum);//相加
	void MultiPoly(Poly& p2, Poly& sum);//相乘
	~Poly();//析构
private:
	Polynode* _head = new Polynode;//直接开辟个头结点
};

2、创建一元多项式

不断创建新节点尾插即可,但要注意若输入的系数为0,没必要插入此节点,直接continue

//创建一元多项式
void Poly::CreatePoly()
{
	Polynode* tail = _head;//尾节点
	int n = 0;
	cout << "请输入一元多项式的项数:" << endl;
	cin >> n;
	for (int i = 0; i < n; ++i)
	{
		int cof, exp;
		cin >> cof >> exp;
		if (cof == 0)
			continue;//如果系数==0,则不插入此节点
		Polynode* newnode = new Polynode(cof, exp);//创建新节点
		tail->_next = newnode;//链接
		tail = newnode;
	}
}

3、节点的尾插

//节点的尾插
void Poly::Push_back(Polynode* node)
{
	Polynode* tail = _head->_next;
	if (tail == nullptr)
	{//若链表为空,直接插入
		_head->_next = node;
	}
	else
	{
		while (tail->_next)
		{	//找到尾节点
			tail = tail->_next;
		}
		tail->_next = node;
	}
}

4、一元多项式相加

//一元多项式的相加(利用一元多项式指数是升序的特点)
//p1 + p2
void Poly::AddPoly(Poly& p2,Poly& sum)
{
	Polynode* cur1 = _head->_next, * cur2 = (p2._head)->_next;//cur用来遍历
	Polynode* head = sum._head;
	while (cur1 && cur2)
	{	//都不为空才会进入循环
		//1、p1的指数<p2的指数
		//2、p1的指数>p2的指数
		//3、p2的指数=p2的指数:
		//   ①、系数相加为0,删除cur1和cur2的对应节点 
		//   ②、不为0,加和到cur1上,尾插到sum后面
		if (cur1->_exp < cur2->_exp)
		{
			head->_next = cur1;
			head = cur1;
			cur1 = cur1->_next;
		}
		else if (cur1->_exp > cur2->_exp)
		{
			head->_next = cur2;
			head = cur2;
			cur2 = cur2->_next;
		}
		else
		{
			//①、系数相加为0
			if (cur1->_coef + cur2->_coef == 0)
			{
				Polynode* next1 = cur1->_next;
				Polynode* next2 = cur2->_next;
				delete cur1;
				delete cur2;
				cur1 = next1;
				cur2 = next2;
			}
			else
			{//②、系数相加不为0
				cur1->_coef = cur1->_coef + cur2->_coef;
				head->_next = cur1;
				head = cur1;
				cur1 = cur1->_next;
				Polynode* next = cur2->_next;
				delete cur2;
				cur2 = next;
			}
		}
	}
	if (cur1)
	{//若cur1不为空
		head->_next = cur1;
	}
	if (cur2)
	{//若cur2不为空
		head->_next = cur2;
	}
}

5、一元多项式相乘

 相乘的逻辑就是双层循环,对于链表怎么双重循环,思路就是对于第一个多项式的第一项乘以第二个多项式的每一项,然后第一个多项式的第二项乘以第二个多项式的每一项....直到乘到结束

//一元多项式的相乘
//p1 * p2
void Poly::MultiPoly(Poly& p2, Poly& sum)
{
	Polynode* cur1 = _head->_next, * cur2 = (p2._head)->_next;//cur用来遍历
	int cofs = 0, exps = 0;
	while (cur1)
	{
		cur2 = (p2._head)->_next;//再次回到头结点的下一位置
		while (cur2)
		{
			cofs = cur1->_coef * cur2->_coef;//系数相乘
			exps = cur1->_exp + cur2->_exp;//指数相加
			Polynode* newnode = new Polynode(cofs, exps);
			sum.Push_back(newnode);
			
			cur2 = cur2->_next;
		}
		cur1 = cur1->_next;
	}
}

6、多项式的打印

 存在特殊情况考虑:

①、若系数为1,指数不为0,只打印x^指数

②、若系数为1,指数为0,只打印1

③、若系数不为0,指数为0,只打印系数

④、若系数为负数,要给系数加上()

//打印一元多项式
void Poly::Print( )
{
	Polynode* cur = _head->_next;
	while (cur)
	{
		//当指数!=0时,才会打印出x
		if (cur->_exp != 0)
		{
			//当系数!=1时,才会打印出系数
			if (cur->_coef != 1)
			{
				if (cur->_coef < 0)
				{
					cout << "(" << cur->_coef;
					cout << ")x^" << cur->_exp;
				}
				else
				{
					cout << cur->_coef;
					cout << "x^" << cur->_exp;
				}
			}
			else
			{//当系数==1时,指数不为0时
				cout << "x^" << cur->_exp;
			}
		}
		else
		{ //若指数为0,只打印系数
			if (cur->_coef != 1)
			{//系数不为1,则只打印系数
				if (cur->_coef < 0)
				{
					cout << "(" << cur->_coef;
					cout << ")";
				}
				else
				{
					cout << cur->_coef;
				}
			}
			else
			{
				cout << "1";//若系数为1,指数为0,则打印1
			}
		}
		cur = cur->_next;

		if (cur != NULL)
		{//最后一项之前才会打印加号
			cout << " + ";//正数打印+
		}
	}
	cout << endl;
}

 7、 Poly的析构函数

//析构函数
Poly::~Poly()
{
	delete _head;
	_head = nullptr;
}

8、完整代码

Poly.h:

#pragma once
#include<iostream>
using namespace std;
//链表的多项式节点
struct Polynode
{
	int _coef;//系数
	int _exp;//指数
	struct Polynode* _next;

	Polynode(int coef = 0,int exp = 0)
		:_next(nullptr)
		,_coef(coef)
		,_exp(exp)
	{}

	~Polynode()
	{
		_next = nullptr;
	}
};

//一元多项式
class Poly
{
public:
	void CreatePoly();//创建
	void Print();//打印
	void Push_back(Polynode* node);//尾插
	void AddPoly(Poly& p2, Poly& sum);//相加
	void MultiPoly(Poly& p2, Poly& sum);//相乘
	~Poly();//析构
private:
	Polynode* _head = new Polynode;//直接开辟个头结点
};

Poly.cpp 

#include"Poly.h"

//创建一元多项式
void Poly::CreatePoly()
{
	Polynode* tail = _head;//尾节点
	int n = 0;
	cout << "请输入一元多项式的项数:" << endl;
	cin >> n;
	for (int i = 0; i < n; ++i)
	{
		int cof, exp;
		cin >> cof >> exp;
		if (cof == 0)
			continue;//如果系数==0,则不插入此节点
		Polynode* newnode = new Polynode(cof, exp);//创建新节点
		tail->_next = newnode;//链接
		tail = newnode;
	}
}

//打印一元多项式
void Poly::Print( )
{
	Polynode* cur = _head->_next;
	while (cur)
	{
		//当指数!=0时,才会打印出x
		if (cur->_exp != 0)
		{
			//当系数!=1时,才会打印出系数
			if (cur->_coef != 1)
			{
				if (cur->_coef < 0)
				{
					cout << "(" << cur->_coef;
					cout << ")x^" << cur->_exp;
				}
				else
				{
					cout << cur->_coef;
					cout << "x^" << cur->_exp;
				}
			}
			else
			{//当系数==1时,指数不为0时
				cout << "x^" << cur->_exp;
			}
		}
		else
		{ //若指数为0,只打印系数
			if (cur->_coef != 1)
			{//系数不为1,则只打印系数
				if (cur->_coef < 0)
				{
					cout << "(" << cur->_coef;
					cout << ")";
				}
				else
				{
					cout << cur->_coef;
				}
			}
			else
			{
				cout << "1";//若系数为1,指数为0,则打印1
			}
		}
		cur = cur->_next;

		if (cur != NULL)
		{//最后一项之前才会打印加号
			cout << " + ";//正数打印+
		}
	}
	cout << endl;
}

//节点的尾插
void Poly::Push_back(Polynode* node)
{
	Polynode* tail = _head->_next;
	if (tail == nullptr)
	{//若链表为空,直接插入
		_head->_next = node;
	}
	else
	{
		while (tail->_next)
		{	//找到尾节点
			tail = tail->_next;
		}
		tail->_next = node;
	}
}

//一元多项式的相加(利用一元多项式指数是升序的特点)
//p1 + p2
void Poly::AddPoly(Poly& p2,Poly& sum)
{
	Polynode* cur1 = _head->_next, * cur2 = (p2._head)->_next;//cur用来遍历
	Polynode* head = sum._head;
	while (cur1 && cur2)
	{	//都不为空才会进入循环
		//1、p1的指数<p2的指数
		//2、p1的指数>p2的指数
		//3、p2的指数=p2的指数:
		//   ①、系数相加为0,删除cur1和cur2的对应节点 
		//   ②、不为0,加和到cur1上,尾插到sum后面
		if (cur1->_exp < cur2->_exp)
		{
			head->_next = cur1;
			head = cur1;
			cur1 = cur1->_next;
		}
		else if (cur1->_exp > cur2->_exp)
		{
			head->_next = cur2;
			head = cur2;
			cur2 = cur2->_next;
		}
		else
		{
			//①、系数相加为0
			if (cur1->_coef + cur2->_coef == 0)
			{
				Polynode* next1 = cur1->_next;
				Polynode* next2 = cur2->_next;
				delete cur1;
				delete cur2;
				cur1 = next1;
				cur2 = next2;
			}
			else
			{//②、系数相加不为0
				cur1->_coef = cur1->_coef + cur2->_coef;
				head->_next = cur1;
				head = cur1;
				cur1 = cur1->_next;
				Polynode* next = cur2->_next;
				delete cur2;
				cur2 = next;
			}
		}
	}
	if (cur1)
	{//若cur1不为空
		head->_next = cur1;
	}
	if (cur2)
	{//若cur2不为空
		head->_next = cur2;
	}
}

//一元多项式的相乘
//p1 * p2
void Poly::MultiPoly(Poly& p2, Poly& sum)
{
	Polynode* cur1 = _head->_next, * cur2 = (p2._head)->_next;//cur用来遍历
	int cofs = 0, exps = 0;
	while (cur1)
	{
		cur2 = (p2._head)->_next;//再次回到头结点的下一位置
		while (cur2)
		{
			cofs = cur1->_coef * cur2->_coef;//系数相乘
			exps = cur1->_exp + cur2->_exp;//指数相加
			Polynode* newnode = new Polynode(cofs, exps);
			sum.Push_back(newnode);
			
			cur2 = cur2->_next;
		}
		cur1 = cur1->_next;
	}
}

//析构函数
Poly::~Poly()
{
	delete _head;
	_head = nullptr;
}

test.cpp

#include"Poly.h"

void TestPoly()
{
	Poly p1,p2,sum1,sum2;
	p1.CreatePoly();
	p2.CreatePoly();
	p1.Print();
	p2.Print();

	cout << endl;
	cout << "p1 * p2的结果为" << endl;
	p1.MultiPoly(p2, sum2);
	sum2.Print();

	cout << endl;
	cout << "p1 + p2的结果为" << endl;
	p1.AddPoly(p2,sum1);
	sum1.Print();
}

int main()
{
	TestPoly();

	return 0;
}

9、运行测试

 

最后,代码还存在一个问题,相同的指数的x项相加后,相乘后没有合并,这里我就不写了 

三、艰难的调试过程(可不看,我自己看的)

在我写完多项式相加后,创建多项式后程序直接给我卡死在这,但是之前测试打印什么的都没问题,那问题可能出现在了AddPoly

经调试发现是AddPoly的插入有问题,尾插的时候什么时候该删除,什么是否不该删除节点我没搞清楚

AddPoly代码逻辑修改完后又出现了问题:但是没有Addpoly的调用,代码打印p2还是没问题,说明加了AddPoly后p2的打印有问题,可能是删除方面出现了问题

经过不断的调试,我发现问题在于调用的顺序,因为调用AddPoly后p2或者p1的部分数据会被删除的,故你想打印p1和p2,必须在调用AddPoly之前再调用,不然就非法访问了,这就是一个很小的问题

 在实现相乘的时候又出错了

 但是如果把AddPoly注释掉就可以正常运行MultiPoly了,还是一样的问题,AddPoly应该放在最后调用,因为他破坏了p1或p2,或者你相乘换个数据,不用p1和p2也行

调用时相加放在后面就可以解决问题了

  • 7
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include <stdio.h> #include <stdlib.h> struct node { // 定义节点结构体 int coef; // 系数 int exp; // 指数 struct node *next; // 指向下一个节点的指针 }; typedef struct node Node; Node* create_node(int coef, int exp) { // 创建一个节点 Node *new = (Node*)malloc(sizeof(Node)); new->coef = coef; new->exp = exp; new->next = NULL; return new; } Node* add_poly(Node *poly1, Node *poly2) { // 两个多项式相加 Node *head = create_node(0, 0); // 头结点,作为新的多项式的起点 Node *p1 = poly1, *p2 = poly2, *p3 = head; while (p1 != NULL && p2 != NULL) { if (p1->exp > p2->exp) { // 计算结果多项式的该项为第一个多项式的当前项 p3->next = create_node(p1->coef, p1->exp); p1 = p1->next; } else if (p1->exp < p2->exp) { // 计算结果多项式的该项为第二个多项式的当前项 p3->next = create_node(p2->coef, p2->exp); p2 = p2->next; } else { // 计算结果多项式的该项为两个多项式的当前项之和,系数相加 p3->next = create_node(p1->coef + p2->coef, p1->exp); p1 = p1->next; p2 = p2->next; } p3 = p3->next; } // 处理没有计算过的多项式项 while (p1 != NULL) { p3->next = create_node(p1->coef, p1->exp); p1 = p1->next; p3 = p3->next; } while (p2 != NULL) { p3->next = create_node(p2->coef, p2->exp); p2 = p2->next; p3 = p3->next; } return head->next; // 返回新的多项式 } void print_poly(Node *poly) { // 输出多项式 Node *p = poly; while (p != NULL) { printf("%dX^%d ", p->coef, p->exp); if (p->next != NULL && p->next->coef > 0) { printf("+ "); } p = p->next; } printf("\n"); } int main() { Node *poly1, *poly2, *result; // 创建第一个多项式 poly1 = create_node(3, 5); poly1->next = create_node(-2, 3); poly1->next->next = create_node(1, 1); // 创建第二个多项式 poly2 = create_node(2, 4); poly2->next = create_node(-7, 3); poly2->next->next = create_node(4, 1); result = add_poly(poly1, poly2); // 两个多项式相加 printf("多项式1:"); print_poly(poly1); // 输出第一个多项式 printf("多项式2:"); print_poly(poly2); // 输出第二个多项式 printf("相加结果:"); print_poly(result); // 输出相加结果 // 释放内存 while (poly1 != NULL) { Node *p = poly1; poly1 = poly1->next; free(p); } while (poly2 != NULL) { Node *p = poly2; poly2 = poly2->next; free(p); } while (result != NULL) { Node *p = result; result = result->next; free(p); } return 0; }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值