基于单链表的多项式问题

上学期的东西了,不想再去细究思路了,直接贴代码,注释很详细

#pragma once
#include<iostream>
using namespace std;
class LinkNode
{
public:
	float coef;//系数
	int expn;//指数
	LinkNode *link;//指向后继的指针域
	LinkNode *plink;//指向前驱的指针域
public:
	LinkNode();
	LinkNode(float co,int ex);
	~LinkNode();
	friend istream& operator>> (istream& input,LinkNode& L);//输入重载
	friend ostream& operator<< (ostream& output,LinkNode& L);//输出重载
	//friend operator= ()
};

#include"LinkNode.h"
#include<iostream>
using namespace std;
LinkNode::LinkNode()
{
	expn = -1;
}
LinkNode::LinkNode(float co,int ex)
{
	coef = co;
	expn = ex;
	link = NULL;
	plink = NULL;
}
LinkNode::~LinkNode()
{}
//istream& operator>> (istream& input,LinkNode& L)
//{
	//input>
//}
ostream& operator<< (ostream& output,LinkNode& L)
{
	if(L.coef > 0)
		output<<"+";
	output<<L.coef;
	if(L.expn > 0)
		output<<"^"<<L.expn;
	return output;
}
#pragma once
#include"LinkNode.h"
#include<iostream>
using namespace std;
class Polynomial
{
protected:
	LinkNode *first;//依旧首指针
	LinkNode *rear;
public:
	Polynomial();
	Polynomial(LinkNode * fir);//复制函数而定义的构造函数
	Polynomial(Polynomial &P);//深复制
	~Polynomial();
	void makeEmpty();
	void input();//输入
	void output();//输出
	void Sort();//指数升序排序
	int Length();//返回元素个数
	void Settle();//整理多项式 包括合并 与排序
	LinkNode * GetHead();
	LinkNode *Getrear();
	void reverse_order();
	friend istream& operator>> (istream& input,Polynomial &P);//重载输入流
	friend ostream& operator<< (ostream& output,Polynomial &P);//重载输出流
	friend Polynomial operator+ (Polynomial &P1,Polynomial &P2);//友元便于操作与不收类函数的限制
	friend Polynomial operator- (Polynomial &P1,Polynomial &P2);
	friend Polynomial operator* (Polynomial &P1,Polynomial &P2);
	void operator= (Polynomial &P);
};

#include"Polynomial.h"
#include<iostream>
using namespace std;
Polynomial::Polynomial()
{
	first = new LinkNode;//开辟头结点,初始化指数域为-1
	rear = first;
}
Polynomial::Polynomial(LinkNode * fir)
{
	first = new LinkNode;
	first->link = fir;//在头结点的后面接上一串
}
Polynomial::Polynomial(Polynomial &P)
{
	LinkNode *srcptr = P.GetHead();
	if(srcptr == NULL)
		exit(1);
	LinkNode *destptr = first = new LinkNode;//初始化当前多项式
	LinkNode *newNode;
	float current_coef;//用于记录当前系数
	int current_expn;//记录当前指数
	while(srcptr->link != NULL)
	{
		current_coef = srcptr->link->coef;
		current_expn = srcptr->link->expn;

		newNode = new LinkNode(current_coef,current_expn);
		destptr->link = newNode;

		srcptr = srcptr->link;
		destptr = destptr->link;
	}
}

Polynomial::~Polynomial()
{
	//makeEmpty();//是在不懂为什么不行 先注释掉
}
void Polynomial::makeEmpty()
{
	LinkNode * del;
	while(first->link != NULL)//如果为空表则头结点的指针域为NULL不会执行循环
	{
		del = first->link ;//不为空表第一次循环的情况下,把第1个结点的指针赋给了del指针
		first->link = del->link ;//把当前要删除的结点的后面一个节点接在头结点指针域上, 在最后循环结束之前最后结点的NULL赋给了first->link,所以会跳出
		delete del ;
	}
}

istream& operator>> (istream& input,Polynomial &P)
{
	LinkNode *last = P.GetHead();//头指针赋值一份
	LinkNode *newNode;
	float current_coef;//用于记录当前系数
	int current_expn;//记录当前指数
	input>>current_coef>>current_expn;
	while(current_coef != 0)
	{
		newNode = new LinkNode(current_coef,current_expn);
		last->link = newNode;
		newNode->plink = last;
		last = last->link;

		input>>current_coef>>current_expn;
	}
	P.rear = last;
	P.Sort();//输入完毕后开始合并 并排序默认升序
	P.Settle();//在排序后直接合并同类项
	return input;

}

ostream& operator<< (ostream& output,Polynomial &P)
{
	LinkNode *current = P.GetHead()->link;
	while(current != NULL)
	{
		cout<<*current;
		current = current->link;
	}

	return output;
}
void Polynomial::Sort()//指数升序排序
{

	LinkNode  *current1,*current2 ;
	for(current1=first->link;current1!=NULL;current1=current1->link)
	{
		for(current2=current1->link;current2!=NULL;current2=current2->link)
		{
			if(current1->expn > current2->expn)
			{
				int expn_temp;//指数临时存储变量
				expn_temp = current1->expn;
				current1->expn = current2->expn;
				current2->expn = expn_temp;
				float coef_temp;//系数临时存储变量
				coef_temp = current1->coef;
				current1->coef = current2->coef;
				current2->coef = coef_temp;
			}
		}
	}
}

int Polynomial::Length()
{
	LinkNode * current = first ;
	int elemnum = 0;
	while(current->link != NULL)//如果头结点指针域为NULL则不执行循环直接返回0值
	{
		current = current->link ;
		elemnum++;
	}
	return elemnum;
}
LinkNode * Polynomial::GetHead()
{
	return first;
}
LinkNode * Polynomial::Getrear()
{
	return rear;
}
void Polynomial::reverse_order()
{
	int elemnum = Length();//调用求长度函数 获取多项式的元素个数
	LinkNode *current1 = first->link; //首端
	LinkNode *current2 = rear;//尾端 开始逆置
	for(int idx = 0; idx < elemnum/2 ;idx++)
	{
		int expn_temp;//指数临时存储变量
		expn_temp = current1->expn;
		current1->expn = current2->expn;
		current2->expn = expn_temp;

		float coef_temp;//系数临时存储变量
		coef_temp = current1->coef;
		current1->coef = current2->coef;
		current2->coef = coef_temp;
		current1 = current1->link;
		current2 = current2->plink;
	}
}

Polynomial operator+ (Polynomial &P1,Polynomial &P2)
{
	P1.Sort(); P2.Sort();//先对两个多项式进行指数升序排序,便于后面的合并
	LinkNode *current1 = P1.GetHead() ->link;//获取两个头指针
	LinkNode *current2 = P2.GetHead() ->link;
	LinkNode *current3;//用于循环跳出后的指针承接
	LinkNode *newNode;//每次重新开辟结点
	LinkNode *last,*pol;//用于记录最后相加结果的头指针,最后要以他为参数返回一个Polynomial类
	last = pol = new LinkNode;

	float coef_elem;
	int expn_elem;
	while(current1!=NULL && current2!=NULL)//在两个指针都不为空的时候进行指数比较,否则跳出
	{
		if(current1->expn < current2->expn)
		{
			coef_elem = current1->coef;
			expn_elem = current1->expn;
			newNode = new LinkNode(coef_elem,expn_elem);

			last->link = newNode;//新开辟的结点连接在last的后面
			last = last->link;

			current1 = current1->link;
			continue;
		}
		if(current1->expn > current2->expn)
		{
			coef_elem = current2->coef;
			expn_elem = current2->expn;
			newNode = new LinkNode(coef_elem,expn_elem);

			last->link = newNode;//新开辟的结点连接在last的后面
			last = last->link;

			current2 = current2->link;
			continue;
		}
		if(current1->expn == current2->expn)//当比较到两个指数相同时候
		{
			if(current1->coef + current2->coef == 0)//系数相加为0 则两指针都后移
			{
				current1 = current1->link;
				current2 = current2->link;
				continue;//如果在指数相等的情况下系数相加为0则两个指针全都后移一位 直接调相下一次循环比较
			}
			if(current1->coef + current2->coef != 0)//如果不等于0 则指定一个加到另一个上 也都后移
			{
				coef_elem = current1->coef + current2->coef;//系数相加
				expn_elem = current1->expn;
		    	newNode = new LinkNode(coef_elem,expn_elem);

			    last->link = newNode;//新开辟的结点连接在last的后面
			    last = last->link;

			    current1 = current1->link;//两个指针都后移一位
				current2 = current2->link;
				continue;
			}
		}
	}
	if(current1==NULL && current2==NULL)//如果循环跳出时 可能是都结束了则直接返回多项式避免了后面的操作
	{
		return Polynomial(pol->link);
	}
	//跳出循环进入NULL判断
	current3 = ((current1 == NULL) ? current2 : current1);
	while(current3 != NULL)
	{
		coef_elem = current3->coef;
		expn_elem = current3->expn;

		newNode = new LinkNode(coef_elem,expn_elem);
		last->link = newNode;//新开辟的结点连接在last的后面
		last = last->link;
		current3 = current3->link;
	}
	return Polynomial(pol->link);//最正常情况下的返回
}
void Polynomial::operator= (Polynomial &P)
{
	//makeEmpty();
	LinkNode *srcptr = P.GetHead();
	if(srcptr == NULL)
		exit(1);
	LinkNode *destptr = first;//初始化当前多项式
	LinkNode *newNode;
	float current_coef;//用于记录当前系数
	int current_expn;//记录当前指数
	while(srcptr->link != NULL)
	{
		current_coef = srcptr->link->coef;
		current_expn = srcptr->link->expn;

		newNode = new LinkNode(current_coef,current_expn);
		destptr->link = newNode;

		srcptr = srcptr->link;
		destptr = destptr->link;
	}
}

void Polynomial::Settle()
{
	LinkNode *current1,*current2;//在默认升序排序后的合并同类项
	LinkNode *del;
	for(current1=first->link;current1->link!=NULL;current1=current1->link)//循环终止条件是关键 外层只需进行到倒数第二个
	{//外层开始从第一个开始循环
		current2 = current1->link;//把后一个的指针赋给2
		for(; ;)
		{//这里的死循环是为了解决 合并后 指针后一问题
			if(current2->expn != current1->expn)//只要条件成立 说明可以跳出内层死循环 外层开始下一次循环
				break;
			if(current2->expn == current1->expn)
			{//2始终在1的后面,确保这一点非常有利于写合并于删除算法
				current1->coef = current1->coef + current2->coef;//系数相加
				del = current2;
				current1->link = del->link;
				delete del;
				current2 = current1->link;
				if(current2 == NULL)//此步骤 是合并算法的最后一步判断标准
					return ;
			}
		}
	}
}

Polynomial operator* (Polynomial &P1,Polynomial &P2)
{
	P1.Sort();P1.Settle();//分别合并同类项 减少运算次数
	P2.Sort();P2.Settle();
	LinkNode *current1 = P1.GetHead()->link;
	LinkNode *last,*pol;
	LinkNode *newNode;
	last = pol = new LinkNode;//开辟新头结点 用于承接相乘之后的多项式
	float elem_coef;
	int elem_expn;
	for(; current1 != NULL; current1 =current1->link)
	{
		LinkNode *current2 = P2.GetHead()->link;//每次外层循环开始都需要把内层指针置为首指针
		for(; current2 != NULL; current2 = current2->link)
		{
			elem_coef = (current1->coef) * (current2->coef);//系数相乘
			elem_expn = (current1->expn) + (current2->expn);//指数相加
			newNode = new LinkNode(elem_coef,elem_expn);//每一次相乘的结果做成结点
			last->link = newNode;//接在pol的后面
			last = last->link;//last指针后移
		}
	}
	Polynomial POL(pol->link);//生成一个多项式
	POL.Sort();POL.Settle();//合并同类项
	return POL;//返回一个多项式对象
}

你可能感兴趣的:(数据结构)