数据结构之链表的应用之一—多项式及其运算

本文介绍了一种使用链表结构来表示和处理多项式的C++实现方法,包括多项式的加法、乘法等基本运算,并通过实例展示了如何输入、输出及计算多项式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CPolynomial.h文件

#pragma once
/*
*Copyright© 中国地质大学(武汉) 信息工程学院
*All right reserved.
*
*文件名称:CPolynomial.h
*摘    要:利用链表结构完成多项式的表示及其运算
*
*当前版本:1.0
*作       者:邵玉胜
*完成日期:2018-04-16
*/


//多项式的类定义
#ifndef POLYNOMIAL_H_
#define POLYNOMIAL_H_
#include<iostream>
using namespace std;

struct  Term                              //多项式节点的定义
{
	float m_dCoef;                               //系数
	int m_nExp;                                  //指数
	Term* m_pLink;
	Term(float c, int e, Term *next = nullptr)
	{
		m_dCoef = c;
		m_nExp = e;
		m_pLink = next;
	}

	Term* InsertAfter(float c, int e);
	friend ostream& operator<<(ostream&, const Term&);
};

class CPolynomial                                        //多项式类定义
{
public:
	CPolynomial() { m_pFirst = new Term(0, -1); }          //构造函数,构造空链表
	~CPolynomial();                                        //析构函数
	CPolynomial(CPolynomial& R);                          //复制构造函数
	CPolynomial& operator = (CPolynomial& R);             //重载赋值运算符
	int maxOrder();                                        //计算最大阶数
	Term* getHead()const { return m_pFirst; }              //取得多项式单链表的表头指针
private:
	Term* m_pFirst;
	friend ostream& operator <<(ostream&, const CPolynomial&);
	friend istream& operator >>(istream&, CPolynomial&);
	friend CPolynomial operator + (CPolynomial&, CPolynomial&);
	friend CPolynomial operator *(CPolynomial&, CPolynomial&);
};

#endif

CPolynomial.cpp文件

#include"Polynomial.h"

Term* Term::InsertAfter(float c, int e) 
{
	//在当前由this指针指示的项(即调用此函数的对象)后面插入一个新项
	m_pLink = new Term(c, e);
	return m_pLink;
}

ostream& operator<<(ostream& out, const Term& term) 
{
	//Term的友元函数,输出一个项x的内容到输出流out中
	if (term.m_dCoef == 0) return out;                  //零系数项,不输出
	out << term.m_dCoef;
	switch (term.m_nExp)
	{
	case 0:
		break;
	case 1:
		out << "X";
		break;
	default:
		out << "X^" << term.m_nExp;
		break;
	}
	return out;
}

CPolynomial::CPolynomial(CPolynomial& P) 
{
	//复制构造函数,用已有多项式对象R初始化当前多项式对象
	m_pFirst = new Term(0, -1);
	Term* destPtr = m_pFirst;
	Term* srcPtr = P.getHead()->m_pLink;
	while (srcPtr != nullptr)
	{
		destPtr->InsertAfter(srcPtr->m_dCoef, srcPtr->m_nExp);
		//在destptr所指定节点后插入新节点,再让destptr指到这个新节点
		srcPtr = srcPtr->m_pLink;
		destPtr = destPtr->m_pLink;
	}
}

CPolynomial& CPolynomial::operator = (CPolynomial& P) {
	//m_pFirst = new Term(0, -1);
	Term* destPtr = m_pFirst;
	Term* srcPtr = P.getHead()->m_pLink;
	while (srcPtr != nullptr)
	{
		destPtr->InsertAfter(srcPtr->m_dCoef, srcPtr->m_nExp);
		//在destptr所指定节点后插入新节点,再让destptr指到这个新节点
		srcPtr = srcPtr->m_pLink;
		destPtr = destPtr->m_pLink;
	}
	return *this;
}

CPolynomial::~CPolynomial() {                 //析构函数
	Term* destPtr = m_pFirst;
	while (destPtr != nullptr) {
		m_pFirst = m_pFirst->m_pLink;
		delete destPtr;
		destPtr = m_pFirst;
	}
}                                      

int CPolynomial::maxOrder() 
{
	//计算最大阶数,当多项式按升序排序时,最后一项中时最大指数者
	Term* current = m_pFirst;
	while (current->m_pLink != nullptr)
		current = current->m_pLink;
	//空表情形,current停留在m_pFirst,否则current停留在表尾节点
	return current->m_nExp;
}

istream& operator>>(istream& in, CPolynomial& P) 
{
	//CPolynomia类的友元函数,从输入流in输入各项,用尾插法建立一个多项式
	Term* rear = P.getHead();
	cout << "输入一个二项式,以0 -1结束" << endl;
	float coef;
	int exp;
	while(in >> coef >> exp){
		if (exp < 0.0)                                //如果指数小于0,就结束循环
			break;
		rear = rear->InsertAfter(coef, exp);                 //插入
		//rear =  rear->m_pLink;
	}
	return in;
}

ostream& operator <<(ostream& out, const CPolynomial& P)
{
	//CPolynomial类的友元函数:输出带附加头结点的多项式链表x
	Term* srcPtr = P.getHead()->m_pLink;
	float coef = 0.0;
	int exp = 0;
	int count = 1;
	while (srcPtr != nullptr) {
		coef = srcPtr->m_dCoef;
		exp = srcPtr->m_nExp;
		if (exp == 0)
			out << coef;
		else if (coef < 0.0)
			out << coef << "X^" << exp;
		else if(coef > 0 && count == 1)
			out << coef << "X^" << exp;
		else 
			out << "+" << coef << "X^" << exp;
		srcPtr = srcPtr->m_pLink;
		count++;
	}
	out << endl;
	return out;
}


//两个多项式的相加运算
CPolynomial operator + (CPolynomial& A, CPolynomial& B) 
{
	//友元函数:两个带附加头结点的按升幂排序的多项式链表的头指针分别是A.m_pFirst与B.m_pFirst
	//返回的是结果多项式的链表
	CPolynomial result;                                           //用于返回的对象
	Term* pResult = result.getHead();
	Term* pA = A.getHead()->m_pLink;                              //指向参数多项式A的第一项的指针
	Term* pB = B.getHead()->m_pLink;                             //指向参数多项式B的第一项的指针
	float dAddCoef = 0.0;
	Term* pLast = nullptr;                                         //用于指向剩下的多项式的第一项
	while (pA != nullptr && pB != nullptr) {                        //如果两个有一个没有达到最后一项,就一直循环
		if (pA->m_nExp == pB->m_nExp) {
			dAddCoef = pA->m_dCoef + pB->m_dCoef;
			if (abs(dAddCoef) > 0.000001)                        //如果系数之和不为0,就将该项插入到结果中
				pResult = pResult->InsertAfter(dAddCoef, pA->m_nExp);
			//pA和pB都指向下一个结点
			pA = pA->m_pLink;
			pB = pB->m_pLink;
		}
		else if (pA->m_nExp < pB->m_nExp) {                       //如果pA指向的项的系数小于pB指向的系数                        
			pResult = pResult->InsertAfter(pA->m_dCoef, pA->m_nExp);        //就在结果中插入pA所指向的项
			pA = pA->m_pLink;                                     //并将pA指向下一结点
		}
		else{                                                     //否则pB->m_nExp > pA->m_nExp
			pResult = pResult->InsertAfter(pB->m_dCoef, pB->m_nExp);
			pB = pB->m_pLink;
		}
	}
	if (pA != nullptr)                                            //如果pA没有加完(剩有大指数项)
		pLast = pA;                                               //指向剩余元素结点的指向指向pA
	else                                                          //否则
		pLast = pB;                                               //指向pB
	while (pLast != nullptr) {                                       //如果pA或者pB不为空
		pResult->InsertAfter(pLast->m_dCoef, pLast->m_nExp);      //就将剩余元素加入到结果中
		pLast = pLast->m_pLink;
	}
	return result;
}

CPolynomial operator * (CPolynomial& A, CPolynomial& B) 
{
	//将一元多项式A和B相乘,乘积9用带附加头节点的单链表表存储
	//返回值为指向存储乘积多项式的单链表头指针
	CPolynomial result;                                            //用于保存结果的临时变量-用于返回
	Term* pResult = result.getHead();

	Term* pA = A.getHead()->m_pLink;                               //指向A的第一个结点
	Term* pB = B.getHead()->m_pLink;                               //指向B的第一个结点

	int AmaxExp = A.maxOrder();                                    //AmaxExp保存A中最大指数
	int BmaxExp = B.maxOrder();                                    //BmaxExp保存B中最大系数
	if (AmaxExp == 0) {                                            //如果A中只有一个常数项
		while (pB != nullptr) {                                    //就将B中的每一项乘以该常数项
			float tempCoef = pA->m_dCoef;
			tempCoef *= pB->m_dCoef;
			pResult = pResult->InsertAfter(tempCoef, pB->m_nExp);
			pB = pB->m_pLink;
		}
	}
	else if (BmaxExp == 0) {                                          //如果B中只有一个常数项
		while (pA != nullptr) {                                       //就将A中的每一项乘以该常数项
			float tempCoef = pB->m_dCoef;
			tempCoef *= pA->m_dCoef;
			pResult = pResult->InsertAfter(tempCoef, pA->m_nExp);
			pA = pA->m_pLink;
		}
	}
	else {                                                                //如果A、B中都函数有X项
		int RmaxExp = A.maxOrder() + B.maxOrder() + 1;                //注意:RmaxExp存放A与B中系数最大项之和
		float *tmArray = new float[RmaxExp];                          //建立一个含有RmaxExp个元素的临时数组
		if (tmArray == nullptr) {                                     //该数组的下标表示结果元素的指数
			cerr << "内存分配失败!" << endl;                       //数组元素的数值表示该元素的系数
			exit(-1);
		}
		for (int i = 0; i < RmaxExp; i++)                             //为数组初始化
			tmArray[i] = 0.0;
		while (pA != nullptr) {                                       //当多项式A还未运行到最后一项
			pB = B.getHead()->m_pLink;                                //每次循环首先将pB指向B的第一项
			while(pB != nullptr){                                     //当多项式B还未运行到最后一项
				int tempExp = pA->m_nExp + pB->m_nExp;                //tempExp保存结果指数
				int tempCoef = pA->m_dCoef * pB->m_dCoef;             //tempCoef保存结果系数
				tmArray[tempExp] += tempCoef;                         //将系数累加到数组中
				pB = pB->m_pLink;                                     //pB指向下一项
			}
			pA = pA->m_pLink;                                         //pA指向下一项
		}

		for (int i = 0; i <= RmaxExp; i++) {
			if (abs(tmArray[i]) > 0.000001) {                          //如果结果数组元素不为0
				pResult = pResult->InsertAfter(tmArray[i], i);         //就将该元素插入到结果中
			}
		}
		delete[] tmArray;
	}
	return result;
}

main.cpp文件(测试文件)

#include"Polynomial.h"

int main() {
	CPolynomial PA, PB, PC;
	cout << "输入PA:" << endl;
	cin >> PA;
	cout << "PA = ";
	cout << PA;

	cout << "输入PB:" << endl;
	cin >> PB;
	cout <<"PB = ";
	cout << PB;

	 
	CPolynomial PD;
	cout << "PA+PB = ";
	PD = PA + PB;
	cout << PD;

	cout << "PA*PB = ";
	PD = PA * PB;
	cout << PD;
	return 0;
}

测试结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值