使用单链表实现多项式的加法和乘法运算(java版)

开始前说些走流程的废话,由于是第一次发博客,表达和讲解方法都不是那么成熟,
  如果有什么地方有待改正,欢迎并感谢亲们在评论区留言
  (让我感受一下捏你们对萌新的善意,谢谢谢谢)
  那么,我们正式开始

单链表的基础概念

利用单链表解决多项式的加法和乘法,实际上就是利用简单的单链表结构体存储数据并进行运算,在解决这个问题之前,我们首先得知道,什么是单链表:
  链表是一种数据结构(存储的数据分散在内存中,每个结点只能也只有它能知道下一个结点的存储位置),而单链表是链表的一种(特点是链表的链接方向是单向的),单链表由不定数量的节点构成,开始于对外暴露的头结点,结束于终端节点(引用为NULL)。
  而节点的组成则包括节点自身存储的对象,以及下一节点的引用next(如下图图1),由于对外暴露的都只有头节点,所以对链表的所有操作,都是直接或者间接地通过其头节点来进行的。
图一                      (图1)

利用单链表解决多项式运算的算法流程

从算法思路开始说起
(此段为详细说明,整体代码在文末,只想看代码可以直接跳过)

一,设计多项式

不管是单项式加法还是乘法,第一步都是设计多项式,
  我的想法是将多项式分解为一个个单项式,设计一个单项式类做节点,再设计链表,将各个单项式连接起来就形成了多项式。
  (单项式类中应含有系数和指数这两种参数,同时还需要有对应的处理方法)

1,设置单项式节点

先建立单项式节点,使单项式可以表达出来
  单项式节点的实际意义
  具体代码如下

package example;

public class PolymialNode {//建立一个多项式节点,包含系数和指数
	private double coef;//系数
	private int index;//指数
	public PolymialNode next;//下一节点的引用
	public PolymialNode() { //初始默认值设置为0
	this(0, 0); 
	}
	 public PolymialNode(double coef, int index) { 
		 this.coef = coef; 
		 this.index = index; 
	 }
	 public double getCoef() {
		 return coef; 
	 } 
	 public void setCoef(double coef) {
		 this.coef = coef; 
	 } 
	 public int getindex() { 
		 return index; 
	 } 
	 public void setindex(int index) {
		 this.index = index; 
	 } 
}

2,连接单项式形成多项式

设置完单项式节点之后,我们就需要把单项式连接起来形成多项式,
此时就运用到了单链表,如图
多项式链表的实际意义
代码部分如下

package example;

public class PolyList {
	 PolymialNode head;//头节点
	 PolymialNode current; //当前单项式节点
	 public PolyList(){
		 head = new PolymialNode();
		 current = head;
		 head.next = null;//设置下一节点头文件默认为空
		 } 
	 public boolean isEmpty() { 
		 return head.next == null;
		 }//判断多项式是否为空
	 public void insert(PolymialNode node) { 
		 current.next = node;
		 current = node; 
	 } //把数据插入多项式链表
	 public String express(){ //设置一个函数表达多项式
		 StringBuilder pl = new StringBuilder(); 
		 PolymialNode node = head.next; 
		 while (node != null) { 
			 pl.append(node.getCoef() + "x^"+node.getindex()); 
			 pl.append(" + "); 
			 node = node.next;
			 } 
		 return pl.substring(0, pl.length() - 2); //头尾皆无数据,故-2
	 }
}

可以看到,代码部分通过单链表,将各个单项式连接起来,这样就形成了多项式

二,多项式加法

因为多项式的加法运算与乘法运算不同,于是先解决多项式加法的问题

匹配指数相同的单项式,并使系数相加

要使系数相加直接加就完了,需要思考的是如何匹配指数相同的单项式。
  我们知道,单链表是顺序存储的,要找到一个元素,必须找到所在单链表的前一位元素(例如找第n位元素必须先找到第n-1位元素,这是由单链表的结构决定的)。
  所以我们要匹配指数相同的项,不能直接按指数相加系数,而需要从头节点开始,统计指数相同的项,并在结果中将系数相同的项相加并保存起来。
那么由于两个多项式项的数量不一定相等,所以我们在创建多项式时除了两个用于计算的多项式外,还需要再新建一个多项式用于统计结果。
  
  以下是加法部分的所有代码,我将它放在多项式链表类PolyLIst中

                      /*加法*/
public static PolyList addPoly(PolyList p, PolyList q) { 
	PolymialNode pnext = p.head.next; 
	PolymialNode qnext = q.head.next; 
	PolyList result = new PolyList(); 
	while (pnext != null && qnext != null) {
		int pindex = pnext.getindex(); 
		int qindex = qnext.getindex(); 
		double pcoef = pnext.getCoef();
		double qcoef = qnext.getCoef(); 
		if (pindex == qindex) { 
			if (pcoef+qcoef != 0) {//指数相同时系数相加并保存到结果多项式result中
				PolymialNode node = new PolymialNode(pcoef + qcoef, pindex); 
				result.insert(node); 
			}
			pnext = pnext.next; 
			qnext = qnext.next; 
		}
		else if(pindex < qindex){ 
			PolymialNode node = new PolymialNode(pnext.getCoef(), pnext.getindex());
			result.insert(node); 
			pnext = pnext.next;
		}
		else{ 
			PolymialNode node = new PolymialNode(qnext.getCoef(), qnext.getindex());
			result.insert(node); 
			qnext = qnext.next; }
		} 
		while (pnext != null) {
			PolymialNode node = new PolymialNode(pnext.getCoef(), pnext.getindex());
			result.insert(node);
			pnext = pnext.next;
		}
		//p多项式已经完成统计
		while (qnext != null) { 
			PolymialNode node = new PolymialNode(qnext.getCoef(), qnext.getindex());
			result.insert(node); 
			qnext = qnext.next; 
		}
		 //q多项式已经完成统计
		return result;
}

因为多项式表达式是从指数小的项开始排列到指数大的项,在遍历单链表时,用指数为参照物比较节点,会有指数相等和不等两种情况,若是相等,则将系数相加指数不变插入到结果链表,若是不等,则将较小的一项添加至结果链表,较大项暂不作处理,继续下一轮比较,如图。三种分支路线  需要注意的是,因为链表下一节点指数必比前一节点大,故不用担心运算错误。
  多项式加法就完成了

三,多项式乘法

话不多述,直接上代码

                       /*乘法*/
	 public static PolyList mulPoly(PolyList p, PolyList q) { 
		 PolymialNode pnext = p.head.next;
		 PolymialNode qnext = q.head.next; 
		 PolyList result = new PolyList();//一共产生p*q个子项(不合并同类项时),由如下两层循环得出
		 while (qnext != null) {
			while (pnext != null) { 
				 double coef = pnext.getCoef() * qnext.getCoef(); 
				 int index = pnext.getindex() + qnext.getindex(); 
				 result.insert(new PolymialNode(coef, index)); 
				 pnext = pnext.next; 
			}
			 qnext = qnext.next; //移动到下一节点
			 pnext = p.head.next;//恢复至链表开头,在进行p次相乘 
		 } 
		 //合并同类项 
		 PolymialNode current = result.head.next;
		 PolymialNode preCurrent = result.head;
		 while (current != null) { 
			 PolymialNode nextNode = current.next; //结果链表当前节点的下一节点
			 while (nextNode != null) { 
				if (nextNode.getindex() == current.getindex()) {//判断指数是否相同
					 current.setCoef(current.getCoef() + nextNode.getCoef()); //设置对应系数的新指数	
				}
				nextNode = nextNode.next;//传下一个节点的值,
			 } 
			 //删除系数为0的项
			 if (current.getCoef() == 0) {
				 preCurrent.next = current.next; 
			 } 
			 current = current.next; 
		}
		return result; 
	}

我们来回忆一下多项式乘法的数学定义,多项式乘法首先就是粗暴的将多项式的所有项进行两两相乘,假设多项式p有m个单项式,多项式q有n个单项式,则有相乘得到的多项式有m*n个单项式,然后再合并同类项,即可得到答案。

得到m*n个单项式

	那么链表中如何做m×n次运算呢,截取上方代码的m×n次运算部分如下
 while (qnext != null) {
			while (pnext != null) { 
				 double coef = pnext.getCoef() * qnext.getCoef(); 
				 int index = pnext.getindex() + qnext.getindex(); 
				 result.insert(new PolymialNode(coef, index)); 
				 pnext = pnext.next; 
			}
			 qnext = qnext.next; 
			 pnext = p.head.next;//恢复初始状态,在进行p次相乘 
		 } 

很简单,就是利用头结点将p链表不断循环至链表首部,分别与q链表节点进行运算。

合并同类项

同上,截取相关代码

PolymialNode current = result.head.next;
	while (current != null) { 
		PolymialNode nextNode = current.next; //结果链表当前节点的下一节点
		while (nextNode != null) { 
			if (nextNode.getindex() == current.getindex()) {//判断指数是否相同
				current.setCoef(current.getCoef() + nextNode.getCoef()); //设置对应系数的新指数
				
			}
			nextNode = nextNode.next;//传下个节点的值, 
		}
		return result;  
	}

可以看到,这部分的操作就和加法其实挺相似的,就是从头开始,复制结果链表的当前节点,与其他所有节点进行比较,指数相同则累加,然后传下一个节点的数据进行比较,若不同,则直接传下一节点值进行比较。

测试

package example;

public class Main {

	public static void main(String[] args) {
		PolyList p1=new PolyList(); //多项式p1
		p1.insert(new PolymialNode(2,0));
		p1.insert(new PolymialNode(-1,1)); 
		p1.insert(new PolymialNode(1,2));
		System.out.println("p1="+p1.express()); 
		PolyList p2=new PolyList(); //多项式p2
		p2.insert(new PolymialNode(-1,0));
		p2.insert(new PolymialNode(1,1));
		p2.insert(new PolymialNode(-1,2)); 
		p2.insert(new PolymialNode(10,4)); 
		System.out.println("p2="+p2.express()); 
		PolyList resultList1= PolyList.addPoly(p1, p2); //相加
		System.out.println("p1+p2="+resultList1.express());
		PolyList resultList2= PolyList.mulPoly(p1, p2); //相乘
		System.out.println("p1*p2="+resultList2.express());
	}

}

运行结果

运行结果

全部代码

最后附上全部代码

PolymialNode类

package example;

public class PolymialNode {//建立一个多项式,包含系数和指数
	private double coef;//系数
	private int index;//指数
	public PolymialNode next;
	//储存该节点下一个借点
	public PolymialNode() { 
	this(0, 0); 
	}
	//初始默认值设置为0
	 public PolymialNode(double coef, int index) { 
		 this.coef = coef; 
		 this.index = index; 
	 }
	 public double getCoef() {
		 return coef; 
	 } 
	 public void setCoef(double coef) {
		 this.coef = coef; 
	 } 
	 public int getindex() { 
		 return index; 
	 } 
	 public void setindex(int index) {
		 this.index = index; 
	 }
	 
	 
}

PolyList类

package example;

public class PolyList {
	 PolymialNode head;//头节点
	 PolymialNode current; //当前单项式节点
	 public PolyList(){
		 head = new PolymialNode();
		 current = head;
		 head.next = null;//设置下一节点头文件默认为空
		 } 
	 public boolean isEmpty() { 
		 return head.next == null;
		 }//判断多项式是否为空
	 public void insert(PolymialNode node) { 
		 current.next = node;
		 current = node; 
	 } //把数据插入多项式链表
	 public String express(){ //设置一个函数表达多项式
		 StringBuilder pl = new StringBuilder(); 
		 PolymialNode node = head.next; 
		 while (node != null) { 
			 pl.append(node.getCoef() + "x^"+node.getindex()); 
			 pl.append(" + "); 
			 node = node.next;
			 } 
		 return pl.substring(0, pl.length() - 2); //头尾皆无数据,故-2
	 }
	 
	                            /*加法*/
	 public static PolyList addPoly(PolyList p, PolyList q) { 
		 PolymialNode pnext = p.head.next; 
		 PolymialNode qnext = q.head.next; 
		 PolyList result = new PolyList(); 
		 while (pnext != null && qnext != null) {
			 int pindex = pnext.getindex(); 
			 int qindex = qnext.getindex(); 
			 double pcoef = pnext.getCoef();
			 double qcoef = qnext.getCoef(); 
			 if (pindex == qindex) { 
				 if (pcoef+qcoef != 0) {//指数相同时系数相加并保存到结果多项式result中
					PolymialNode node = new PolymialNode(pcoef + qcoef, pindex); 
					result.insert(node); 
				 }
				 pnext = pnext.next; 
				 qnext = qnext.next; 
			 }
			 else if(pindex < qindex){ 
				 PolymialNode node = new PolymialNode(pnext.getCoef(), pnext.getindex());
				 result.insert(node); 
				 pnext = pnext.next;
			}
			 else{ 
				 PolymialNode node = new PolymialNode(qnext.getCoef(), qnext.getindex());
				 result.insert(node); 
				 qnext = qnext.next; }
			 } 
		 while (pnext != null) {
			 PolymialNode node = new PolymialNode(pnext.getCoef(), pnext.getindex());
			 result.insert(node);
			 pnext = pnext.next;
		 }
		 //p多项式已经完成统计
		 while (qnext != null) { 
			 PolymialNode node = new PolymialNode(qnext.getCoef(), qnext.getindex());
			 result.insert(node); 
			 qnext = qnext.next; 
		}
		 //q多项式已经完成统计
		 return result;
	 }
	                             /*乘法*/
	 public static PolyList mulPoly(PolyList p, PolyList q) { 
		 PolymialNode pnext = p.head.next;
		 PolymialNode qnext = q.head.next; 
		 PolyList result = new PolyList();//一共产生p*q个子项(不合并同类项时),由如下两层循环得出
		 while (qnext != null) {
			while (pnext != null) { 
				 double coef = pnext.getCoef() * qnext.getCoef(); 
				 int index = pnext.getindex() + qnext.getindex(); 
				 result.insert(new PolymialNode(coef, index)); 
				 pnext = pnext.next; 
			}
			 qnext = qnext.next; //移动到下一节点
			 pnext = p.head.next;//恢复至链表开头,在进行p次相乘 
		 } 
		 //合并同类项 
		 PolymialNode current = result.head.next;
		 PolymialNode preCurrent = result.head;
		 while (current != null) { 
			 PolymialNode nextNode = current.next; //结果链表当前节点的下一节点
			 while (nextNode != null) { 
				if (nextNode.getindex() == current.getindex()) {//判断指数是否相同
					 current.setCoef(current.getCoef() + nextNode.getCoef()); //设置对应系数的新指数	
				}
				nextNode = nextNode.next;//传下一个节点的值,
			 } 
			 //删除系数为0的项
			 if (current.getCoef() == 0) {
				 preCurrent.next = current.next; 
			 } 
			 current = current.next; 
		}
		return result; 
	}
}

Main类

package example;

public class Main {

	public static void main(String[] args) {
		PolyList p1=new PolyList(); //多项式p1
		p1.insert(new PolymialNode(2,0));
		p1.insert(new PolymialNode(-1,1)); 
		p1.insert(new PolymialNode(1,2));
		p1.insert(new PolymialNode(-9,4)); 
		p1.insert(new PolymialNode(2,7));
		p1.insert(new PolymialNode(-7,9));
		System.out.println("p1="+p1.express()); 
		PolyList p2=new PolyList(); //多项式p2
		p2.insert(new PolymialNode(-1,0));
		p2.insert(new PolymialNode(1,1));
		p2.insert(new PolymialNode(-1,2)); 
		p2.insert(new PolymialNode(10,4)); 
		p2.insert(new PolymialNode(3,8));
		p2.insert(new PolymialNode(5,10));
		p2.insert(new PolymialNode(9,11));
		System.out.println("p2="+p2.express()); 
		PolyList resultList1= PolyList.addPoly(p1, p2); //相加
		System.out.println("p1+p2="+resultList1.express());
		PolyList resultList2= PolyList.mulPoly(p1, p2); //相乘
		System.out.println("p1*p2="+resultList2.express());
	}

}
  • 10
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值