线性表的应用:一元多项式的表示及其相加

本文讨论了一元多项式的两种存储表示方法,顺序表示用于低幂且均匀分布的情况,链式表示用于高幂度且稀疏的多项式。通过实例展示了多项式相加的实现,并提供了两种结构的代码示例。

     以下内容主要参考了严蔚敏版的数据结构教材,仅为加强学习,不做其他用途。
     一元多项式pn(x)=p0+p1x+p2x2+...+pnxnp_n(x)=p_0+p_1x+p_2x^2+...+p_nx^npn(x)=p0+p1x+p2x2+...+pnxn一共有n+1n+1n+1个系数,在计算机中可以用线性表来表示。每一个节点的数据域存储每一项的系数:第0个节点存储系数p0p_0p0,第1个节点存储系数p1p_1p1,第n个节点存储系数pnp_npn。每一项的指数默认隐含在系数里面,而不用额外的空间来存储。第0个节点的指数为0,第1个节点的指数为1,第n个节点的指数为n。这样的话一个最高次幂为n的多项式需要n+1n+1n+1个节点来存储,如果某个次幂的数据项的没有的话,比如说x5x^5x5项,那么该数据项对应的线性表中的存储的数据就为0。(顺序表示和链式表示一样)
     两个一元多项式的相加其实很简单,对于相加得到的结果多项式的数据项一般包含两部分:一部分是两个多项式中幂次相同的数据项的系数相加得到新的系数的幂次项,另一部分是两个一元多项式中其它的幂次项。如果采用这样的数据结构来表示一元多项式,那么一元多项式的相加就很简单了。只需要将表示两个一元多项式的两个线性表的对应节点的数据相加就可以了。两个多项式的第0个节点的数据相加,第1个节点的数据相加,第2个节点的数据相加,直到到达某个线性表的最后一个节点为止。如果某一个表示一元多项式的线性表还没有到达最后一个节点,那么这个线性表中剩余的元素直接复制到最后的相加结果的线性表中就可以了。如图1所示

 
图1.

     一元多项式的这种表示对于幂次较低且数据项的幂次分布比较均匀的时候还可以使用,但是对于例如p(x)=1+3x10000+5x300000p(x)=1+3x^{10000}+5x^{300000}p(x)=1+3x10000+5x300000这种,最高次幂很高但是幂次分布又非常稀疏的多项式。如果用这种表示的话会浪费巨大的空间来存储不存在的幂次的数据项,为了避免存储不存在的幂次的数据项而浪费巨大的空间,下面采用另一种节点结构来存储一元多项式,如图2所示。

 
图2.

     新的结构的每一个节点有两个数据项,分别用来存储幂次项的系数和指数且不存储系数为0的幂次项,图2是多项式p(x)=1+3x10000+5x300000p(x)=1+3x^{10000}+5x^{300000}p(x)=1+3x10000+5x300000的新的结构的线性链表的存储结构,可以看出这样节省了大量的空间。对应于线性表的两种存储结构:顺序存储和链式存储,一元多项式也可以有两种存储表示。在实际的应用中,如果只对多项式进行求值而不改变多项式的系数和指数,则采用顺序存储。否则就应该采用链式存储。
     一元多项式的相加肯定会改变多项式的系数,因此采用的是链式存储结构。下面直接上代码并测试多项式p1(x)=7+3x+9x8+5x17p_1(x)=7+3x+9x^8+5x^{17}p1(x)=7+3x+9x8+5x17和多项式p2(x)=8x+22x7−9x8p_2(x)=8x+22x^7-9x^8p2(x)=8x+22x79x8,测试结果如图3所示。

#pragma once
#include <iostream>
using namespace std;
class PolynomialNode
{
private:
	int exponent;
	float coefficient;
	PolynomialNode* next;
public:
	PolynomialNode()
	{
		exponent=-1;
		coefficient=0.0;
		next = nullptr;
	}
	PolynomialNode(float c_value, int e_value )
	{
		exponent = e_value;
		coefficient = c_value;
		next = nullptr;
	}
	PolynomialNode* getNext()
	{
		return next;
	}
	int getExponent()
	{
		return exponent;
	}
	float getCoefficient()
	{
		return  coefficient;
	}
	void setNext(PolynomialNode* p_value)
	{
		next = p_value;
		return;
	}
};
class Polynomial
{
private:
	int length;
	PolynomialNode* head;
public:
	Polynomial()
	{
		length = 0;
		head = new PolynomialNode();
	}

	Polynomial(const Polynomial& original)
	{
		cout << "This is copy constructor." << endl;
		int nodeIndex = 1;
		length = 0;
		head = new PolynomialNode();
		while (nodeIndex <= original.length)
		{
			PolynomialInsert(original.getElementCoefficient(nodeIndex), original.getElementExponent(nodeIndex));
			nodeIndex++;
		}
	}

	~Polynomial()
	{
		PolynomialNode* current = head;
		PolynomialNode* next = head->getNext();
		while (next != nullptr)
		{
			delete current;
			current = next;
			next = next->getNext();
		}
		delete current;
	}
	int PolynomialInsert(float c_value, int e_value);
	int PolynomialLength();
	int getElementExponent(int position) const;
	float getElementCoefficient(int position) const;
	void printPolynomial();
};

int Polynomial::PolynomialInsert(float c_value, int e_value)
{
	PolynomialNode* priorNode = nullptr;
	PolynomialNode* currentNode = head;
	PolynomialNode* insertNode = new PolynomialNode(c_value, e_value);
	priorNode = currentNode;
	currentNode = currentNode->getNext();
	while (currentNode != nullptr)
	{
		if (currentNode->getExponent() < e_value)
		{
			priorNode = currentNode;
			currentNode = currentNode->getNext();
		}
		else
		{
			break;
		}
	}
	if (currentNode == nullptr)
	{
		priorNode->setNext(insertNode);
	}
	else
	{
		if (currentNode->getExponent() == e_value)
		{
			cout << "PolynomialInsert:Exponent element is already exist." << endl;
			return 0;
		}
		else
		{
			insertNode->setNext(currentNode);
			priorNode->setNext(insertNode);
		}
	}
	length++;
	return 1;
}

int Polynomial::PolynomialLength()
{
	return length;
}

float Polynomial::getElementCoefficient(int position) const
{
	PolynomialNode* currentNode = head->getNext();
	int currentPosition = 1;
	if ((position < 1) || (position > length))
	{
		while(1)
		{ 
		    cout << "Element index error. Polynomial length is" << length << endl;
		}
	}
	while ((currentPosition != position) && (currentNode != nullptr))
	{
		currentPosition++;
		currentNode = currentNode->getNext();
	}
	return currentNode->getCoefficient();
}

int Polynomial::getElementExponent(int position) const
{
	PolynomialNode* currentNode = head->getNext();
	int currentPosition = 1;
	if ((position < 1) || (position > length))
	{
		while (1)
		{
			cout << "Element index error. Polynomial length is" << length << endl;
		}
	}
	while ((currentPosition != position) && (currentNode != nullptr))
	{
		currentPosition++;
		currentNode = currentNode->getNext();
	}
	return currentNode->getExponent();
}

void Polynomial::printPolynomial()
{
	if (length == 0)
	{
		cout << "The Polynomial is not exist." << endl;
		return;
	}
	int isFirstElement = 1;
	PolynomialNode* currentNode = head->getNext();
	while (currentNode != nullptr)
	{
		if(currentNode->getCoefficient()>0)
		{
			if (isFirstElement)
			{
				if (currentNode->getExponent() == 0)
				{
					cout << currentNode->getCoefficient();
				}
				else
				{
					if (currentNode->getExponent() == 1)
					{
						cout << currentNode->getCoefficient() << "X";
					}
					else
					{
						cout << currentNode->getCoefficient() << "X^" << currentNode->getExponent();
					}
				}
				isFirstElement = 0;
			}
			else
			{
				if (currentNode->getExponent() == 1)
				{
					cout << "+" << currentNode->getCoefficient() << "X";
				}
				else
				{
					cout << "+" << currentNode->getCoefficient() << "X^" << currentNode->getExponent();
				}
			}
		}
		else
		{
			if (isFirstElement)
			{
				if (currentNode->getExponent() == 0)
				{
					cout << currentNode->getCoefficient();
				}
				else
				{
					if (currentNode->getExponent() == 1)
					{
						cout << currentNode->getCoefficient() << "X";
					}
					else
					{
						cout << currentNode->getCoefficient() << "X^" << currentNode->getExponent();
					}
				}
				isFirstElement = 0;
			}
			else
			{
				if (currentNode->getExponent() == 1)
				{
					cout << currentNode->getCoefficient() << "X";
				}
				else
				{
					cout << currentNode->getCoefficient() << "X^" << currentNode->getExponent();
				}
			}
		}
		currentNode = currentNode->getNext();
	}
	cout << endl;
	return;
}

void addPolynomial(Polynomial &p_plus, Polynomial p1, Polynomial p2)
{
	float plus_sum_coefficient = 0.0;
	int p1_length = p1.PolynomialLength();
	int p2_length = p2.PolynomialLength();

	int currentNodeP1Position = 1;
	int currentNodeP2Position = 1;

	while ((currentNodeP1Position <= p1_length) && (currentNodeP2Position <= p2_length))
	{
		if (p1.getElementExponent(currentNodeP1Position) < p2.getElementExponent(currentNodeP2Position))
		{
			p_plus.PolynomialInsert(p1.getElementCoefficient(currentNodeP1Position), p1.getElementExponent(currentNodeP1Position));
			currentNodeP1Position++;
		}
		else if (p1.getElementExponent(currentNodeP1Position) > p2.getElementExponent(currentNodeP2Position))
		{
			p_plus.PolynomialInsert(p2.getElementCoefficient(currentNodeP2Position), p2.getElementExponent(currentNodeP2Position));
			currentNodeP2Position++;
		}
		else
		{
			plus_sum_coefficient = p1.getElementCoefficient(currentNodeP1Position) + p2.getElementCoefficient(currentNodeP2Position);
			if (plus_sum_coefficient!=0)
			{
				p_plus.PolynomialInsert(plus_sum_coefficient, p2.getElementExponent(currentNodeP2Position));
			}
			currentNodeP1Position++;
			currentNodeP2Position++;
		}
	}

	while (currentNodeP1Position <= p1_length)
	{
		p_plus.PolynomialInsert(p1.getElementCoefficient(currentNodeP1Position), p1.getElementExponent(currentNodeP1Position));
		currentNodeP1Position++;
	}

	while (currentNodeP2Position <= p2_length)
	{
		p_plus.PolynomialInsert(p2.getElementCoefficient(currentNodeP2Position), p2.getElementExponent(currentNodeP2Position));
		currentNodeP2Position++;
	}
	return;
}
int main()
{
	Polynomial p1;
	Polynomial p2;
	Polynomial p_plus;
	/* Create the polynomial p2*/
	p1.PolynomialInsert(7.0, 0);
	p1.PolynomialInsert(3.0, 1);
	p1.PolynomialInsert(9.0, 8);
	p1.PolynomialInsert(5.0, 17);

	/* Create the polynomial p2*/
	p2.PolynomialInsert(8.0, 1);
	p2.PolynomialInsert(22.0, 7);
	p2.PolynomialInsert(-9.0, 8);

	addPolynomial(p_plus,p1, p2);

	cout << "The polynomial p1 is:" << endl;
	p1.printPolynomial();
	cout << "The polynomial p2 is:" << endl;
	p2.printPolynomial();
	cout << "The polynomial p_plus is:" << endl;
	p_plus.printPolynomial();
	return 1;
}
 
图3.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qqssss121dfd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值