这篇文章讲述的是数据结构部分的多项式的表示及相加操作的java实现,如有错误或者不当之处,还望各位大神批评指正。
什么是一元多项式?
- 设 a0,a1,…,an都是数域 F 中的数, n 是非负整数,那么表达式anxn +an-1xn-1+…+a2x2 +a1x+ a0(an≠0) 叫做数域 F上一个文字 x 的多项式或一元多项式。
- 在多项式中,a0叫做零次多项式或常数项,a1x 叫做一次项,一般,aix 叫做i次项,ai 叫做 i 次项的系数。一元多项式用符号 f(x),g(x),…来表示。
概念比较抽象,简单理解为形如Pn(x) = p0 + p1x + p2x^2 + p3x^3 + … + pnx^n的式子,其中符号’^’表示次方,如x^2表示x的二次方,p1…pn为常数。
如何使用java表示一元多项式
使用java表示一元多项式,根据一元多项式的特点可以将一元多项式做如下表示
代码实现
/*元素类型*/
class Element{
int base ; //底数
int index ; //指数
Element next ; //下一个元素的指针
}
一元多项式类型的相关操作
一元多项式数据结构的类型的常用操作有:
1. 初始化init()
2. 添加元素put()
3. 格式化format()
4. 打印print()
初始化方法init()
- 初始化需要的操作有:
- 为头指针分配空间
- 改变尾指针指向
- 数据域为-1
- 代码实现:
/**
* @explain init方法: 初始化多项式
* @throws
* @author 叶清逸
* @date 2018年7月29日 下午12:40:12
*/
public void init(){
/*初始化头结点*/
head = new Element() ;
head.base = -1 ;
head.index = -1 ;
/*初始化头尾指针*/
head.next = null ;
tail = head ;
}
添加元素put()
添加元素操作主要的步骤有:
- 初始化节点,分配空间
- 传入数据
- 改变尾指针指向
代码实现
/**
* @explain put方法: 向多项式中添加元素,相当于创建多项式
* @param base 底数
* @param index 指数
* @throws
* @author 叶清逸
* @date 2018年7月29日 下午12:48:23
*/
public void put(int base , int index){
/*初始化节点*/
Element elem = new Element();
/*填入数据*/
elem.base = base ;
elem.index = index ;
elem.next = null ;
/*改变尾指针指向*/
tail.next = elem ;
tail = elem ;
}
格式化方法format()
格式化操作主要实现三个目的:
- 使指数较大的排在前边
- 合并同指数的项
- 去掉底数为零的项
代码实现:
/**
* @explain format方法: 格式化多项式,按指数的从大到小排序,去掉底数为零的项
* @throws
* @author 叶清逸
* @date 2018年7月29日 下午1:38:00
*/
public void format(){
/**
* 一:指数较大的放在前边
*/
/*使用冒泡排序*/
Element pre = head ;
Element t = tail ; //保存每次遍历的尾节点
while(pre.next != t){
while(pre.next != t){
/*使用指针p和q分别指向准交换的指针*/
Element p = pre.next ;
Element q = p.next ;
/*若前边的元素p的指数小于后边的指针q,交换位置*/
if(p.index < q.index){
p.next = q.next ;
q.next = p ;
pre.next = q ;
/*若交换的节点为每次循环的尾节点改变尾指针的指向*/
if(q == t){
t = p ;
}
/*若交换的尾整个多项式链的尾节点也得改变指针的指向*/
if(q == tail){
tail = p ;
}
}
pre = pre.next ;
}
t = pre ; //下次遍历的尾指针为当前指针
pre = head ; //下次遍历的头指针仍然为head
}
/**
* 二:合并指数相同的项
*/
/*初始化遍历指针*/
Element p = head.next ;
while(p.next != tail && p != tail){ //外层循环遍历整个多项式链
/*初始化内层循环的遍历指针*/
Element q = p.next ;
Element pre2 = p ; //记录节点的前驱节点,便于删除
while(q != tail){ //内层循环遍历该节点之后的节点
/*若指数相同则合并*/
if(p.index == q.index){
p.base += q.base ;
pre2.next = q.next ;
/*若删除的节点是尾节点则改变尾节点指向*/
if(q == tail){
tail = p ;
}
}
pre2 = pre2.next ;
q = q.next ;
}
p = p.next ;
}
/**
* 三、去掉底数为零的项
*/
/*初始化遍历指针*/
Element p2 = head ;
while(p2 != null && p2.next != null){
/*获取指针所指元素*/
Element e = p2.next ;
/*若该元素的底数为0则删除该元素*/
if(e.base == 0){
p2.next = e.next ;
/*若删除的节点为尾节点,改变尾指针指向*/
tail = p2 ;
}
p2 = p2.next ;
}
}
特别注意:删除或交换最后一项时注意修改尾指针的指向
打印方法print()
打印方法较为简单,遍历整个链表即可
代码实现:
/**
* @explain print方法: 打印多项式
* @throws
* @author 叶清逸
* @date 2018年7月29日 下午12:55:39
*/
public void print(){
/*循环遍历每一个节点*/
Element p = head.next ;
while(p != null){
/*第一个节点特殊处理*/
if(p == head.next){
/*若为常数*/
if(p.index == 0){
/*打印此常数*/
System.out.print(p.base);
/*指针下移*/
p = p.next ;
}else{
/*打印该节点*/
System.out.print(p.base+"*x^"+p.index);
/*指针下移*/
p = p.next ;
}
}else{
/*若为常数*/
if(p.index == 0){
/*打印此常数*/
System.out.print(" + "+p.base);
/*指针下移*/
p = p.next ;
}else{
/*打印该节点*/
System.out.print(" + "+p.base+"*x^"+p.index);
/*指针下移*/
p = p.next ;
}
}
}
System.out.println();
}
一元多项式的加减法
加法plus()
一元多项式的加法主要思想是,使用p1中的每一项对比p2中的每一项,若指数相同则底数相加后删除p2中的该项,最后把剩余的项加入p1中
代码实现:
/**
* @explain add方法: 多项式相加
* @param polyn 要加的多项式
* @throws
* @author 叶清逸
* @date 2018年7月29日 下午6:05:18
*/
public void plus(Polynomial polyn){
/*初始化遍历指针分别指向本多项式链和要插入的多项式链*/
Element pre1 = head ;
while(pre1 != null &&pre1 != tail){ //外层循环分别遍历本多项式的每个节点
Element p = pre1.next ;
Element pre2 = polyn.head ;
while(pre2 != null && pre2 != polyn.tail){ //内层循环分别遍历要判断是否合并的节点
Element q = pre2.next ;
/*若两个节点的指数相同则相加*/
if(p.index == q.index){
p.base += q.base ;
/*删除节点,若删除的节点为尾节点,改变尾节点指向*/
if(q == polyn.tail){
polyn.tail = pre2 ;
pre2.next = q.next ;
}else{
pre2.next = q.next ;
}
}
pre2 = pre2.next ;
}
pre1 = pre1.next ;
}
/*将剩余的项添加到多项式链*/
Element p = polyn.head.next ;
while(p != null){
this.put(p.base, p.index);
p = p.next ;
}
}
减法
减法主要实现步骤有:
- 将p2中的每一项的底数乘以-1
- 将p2与p1相加
代码实现
/**
* @explain minus方法: 多项式相减
* @param polyn 调用方法的一元多项式减去传入的一元多项式
* @throws
* @author 叶清逸
* @date 2018年7月29日 下午11:03:52
*/
public void minus(Polynomial polyn){
/*将要加的多项式乘-1*/
Element p = polyn.head ;
while(p.next != null){
Element elem = p.next ;
elem.base *= -1 ;
p = p.next ;
}
/*再相加*/
this.plus(polyn);
}
示例代码
加法
/*求8x²-7x+5与3x²-4x+1之和*/
Polynomial polyn = new Polynomial() ;
polyn.init();
polyn.put(5,3) ;
polyn.put(7,8) ;
polyn.put(9,15) ;
polyn.put(0,0) ;
polyn.format();
System.out.print("P1: ");
polyn.print();
Polynomial polyn2 = new Polynomial() ;
polyn2.init();
polyn2.put(2, 0);
polyn2.put(6, 3);
polyn2.put(-7, 8);
polyn2.put(0,0) ;
polyn2.format();
System.out.print("P2: ");
polyn2.print();
/*多项式P1加上P2*/
polyn.plus(polyn2);
polyn.format();
System.out.print("多项式之和为:");
polyn.print();
- 运行结果:
P1: 9*x^15 + 7*x^8 + 5*x^3
P2: -7*x^8 + 6*x^3 + 2
多项式之和为:9*x^15 + 11*x^3 + 2
减法
/*求8x²-7x+5与3x²-4x+1之和*/
Polynomial polyn = new Polynomial() ;
polyn.init();
polyn.put(5,3) ;
polyn.put(7,8) ;
polyn.put(9,15) ;
polyn.put(0,0) ;
polyn.format();
System.out.print("P1: ");
polyn.print();
Polynomial polyn2 = new Polynomial() ;
polyn2.init();
polyn2.put(2, 0);
polyn2.put(6, 3);
polyn2.put(-7, 8);
polyn2.put(0,0) ;
polyn2.format();
System.out.print("P2: ");
polyn2.print();
/*多项式P1减去P2*/
polyn.minus(polyn2);
polyn.format();
System.out.print("多项式之差为:");
polyn.print();
- 执行结果:
P1: 9*x^15 + 7*x^8 + 5*x^3
P2: -7*x^8 + 6*x^3 + 2
多项式之差为:9*x^15 + 14*x^8 + -1*x^3 + -2