一、课程设计目的和要求
目的:深入理解数据结构的基本理论,掌握数据存储结构的设计方法,掌握基于数据结构的各种操作的实现方法,训练对基础知识和基本方法的综合运用能力,增强对算法的理解能力,提高软件设计能力。在实践中培养独立分析问题和解决问题的作风和能力。
要求:熟练运用Java语言、基本数据结构和算法的基础知识,独立编制一个具有中等难度的、解决实际应用问题的应用程序。通过题意分析、选择数据结构、算法设计、编制程序、调试程序、软件测试、结果分析、撰写课程设计报告等环节完成软件设计的全过程,不断地完善程序以提高程序的性能。
二、题意说明及分析
一元多项式的相加运算,采用多项式排序单链表。
多项式排序单链表类PolySinglyList<T>增加以下成员方法。
public class PolySinglyList<T extends Comparable<? super T> & Addible<? super T>>
extends SortedSinglyList<T>
{
// C(x)=A(x)+B(x),返回this(A)和list相加(B)的多项式(C),不改变this和list。
// 算法不调用深拷贝和addAll(list),将A和B相加的元素复制插入结点到C多项式排序单链表
PolySinglyList<T> union(PolySinglyList<T> list)
}
Polynomial多项式类使用PolyDoublyList<T>对象作为成员变量,实现以下方法。
public boolean equals(Object obj) //比较两个多项式是否相等,覆盖
三、算法设计与分析
用两个按指数升序的单链表遍历节点,依次比较。首先我的思路是要先创建空的一元多项式排序单链表,然后利用项数组进行赋值。在这个一元多项式的相加中,用p、q来遍历两条单链表,项按指数升序进行排序,然后当两项相加时,规则是,如果项的指数相同,则系数相加减,若系数和为零,则删除这一项,多余的项插入到链表中。
四、源程序
1.创建接口
package Finalwork;
public interface Addible<T>
{
public void add(T t);
public boolean removable();
}
2.创建节点Node
package Finalwork;
public class Node<T> {
public T data;
public Node<T> next;
public Node(T data,Node<T> next){
this.data=data;
this.next=next;
}
public Node(){
this(null,null);
}
public String toString(){
return this.data.toString();
}
}
3.创建节点PolyNode实现Addible接口
package Finalwork;
public class PolyNode implements Comparable<PolyNode>,Addible<PolyNode>
{
private int coef; //系数
private int expo; //指数
protected PolyNode next;
public PolyNode()//无参构造
{
this(0,0);
}
public PolyNode(int coef , int expo)//有参构造
{
this.coef = coef;
this.expo = expo;
this.next = null;
}
public PolyNode(PolyNode p) //拷贝构造
{
this(p.coef , p.expo);
}
public boolean equals(Object obj) //equals方法 比较两项是否相等
{
if(this == obj)
return true;
if(!(obj instanceof PolyNode))
return false;
PolyNode term = (PolyNode) obj;
return this.coef == term.coef && this.expo == term.expo;
}
public PolyNode(String str)//参数为一个项时 得到项的系数和指数
{
if(str.charAt(0) == '+')
str = str.substring(1);//去掉+号
int i = str.indexOf('x');
if(i == -1)// 没有x,指数就为0
{
this.coef = Integer.parseInt(str);
this.expo = 0;//指数置0
}else {
String str1 = str.substring(0 , i);//截取x之前的系数
if(str1.equals("-"))//为负号 系数为-1
{
this.coef = -1;
}else {
this.coef = Integer.parseInt(str1);
}
i = str.indexOf('^');//寻找^符号
if(i == -1)
this.expo = 1;
else
this.expo = Integer.parseInt(str.substring(i + 1));
}
}
public String toString()//重写toString方法 具体表示多项式
{
String str = this.coef > 0 ? "+" : "-";
if(this.expo == 0 || this.expo > 0 && this.coef != 1 && this.coef != -1)
{
str += Math.abs(this.coef); //显示系数的绝对值 为1或-1时不需要显示
}
if(this.expo > 0)
str += "x";//指数为0时 任何数的0次方都为0 不需要输出
if(this.expo > 1)
str += "^" + this.expo;//指数为1时 任何数的1次方等于本身 不需要输出指数 其余情况需要输出
return str;
}
public int compareTo(PolyNode a)//比较两项大小
{
return (this.expo < a.expo ? -1 : (this.expo == expo ? 0 : 1));
}
public void add(PolyNode p)//+
{
if(this.compareTo(p) == 0)
this.coef += p.coef;
}
public boolean removable()//删除
{
return this.coef == 0;
}
public int getCoef()
{
return coef;
}
public void setCoef(int coef)
{
this.coef = coef;
}
public int getExpo()
{
return expo;
}
public void setExpo(int expo)
{
this.expo = expo;
}
}
}
}
4.创建SinglyList类继承根类
package Finalwork;
public class SinglyList<T> extends Object{
public Node<T> head;
public SinglyList()
{
this.head = new Node<>();
}
public SinglyList(T[] values)
{
this();
Node<T> rear = this.head;
for (int i = 0 ; i < values.length ; i++)
{
if(values[i] != null)
{
rear.next = new Node<>(values[i] , null);
rear = rear.next;
}
}
}
public boolean isEmpty()
{
return this.head.next == null;
}
public T get(int i)
{
Node<T> p = this.head.next;
for (int j = 0 ; p != null && j < i ; j++)
p = p.next;
return (i >= 0 && p != null) ? p.data : null;
}
public void set(int i , T x)
{
if(i < 0 || i > size())
{
throw new IndexOutOfBoundsException(i + "");
}
if(x == null)
throw new NullPointerException("x == null");
Node<T> p =this.head.next;
for (int j = 0 ; p != null && j < i ; j++)
p = p.next;
p.data = x;
}
public int size()
{
int len = 0;
Node<T> p = this.head.next;
if(p == null)
return -1;
while (p != null)
{
len++;
p = p.next;
}
return len;
}
public String toString()
{
String str = this.getClass().getName() + "";
for(Node<T> p = this.head.next ; p != null ; p = p.next)
str += p.data.toString() + (p.next != null ? "," : "");
return str + ")";
}
public Node<T> insert(int i , T x)//i为插入位置 i<0 头插入 i>长度 尾插入
{
if(x == null)
return null;
Node<T> front = this.head;
for (int j = 0 ; front.next != null && j < i ; j++)
front = front.next;
front.next = new Node<>(x , front.next);
return front.next;
}
public Node<T> insert(T x)//尾插入
{
return insert(Integer.MAX_VALUE , x);
}
public T remove(int i)//删除第i个元素 删除成功返回删除元素 否则返回null
{
Node<T> front = this.head;
for(int j = 0 ; front.next != null && j < i ; j++)
front = front.next;
if(i >= 0 && front.next != null)
{
T x = front.next.data;
front.next = front.next.next;
return x;
}
return null;
}
public void clear()//清空链表
{
this.head.next = null;
}
}
5.创建SortedSinglyList类继承SinglyList类
package Finalwork;
public class SortedSinglyList<T extends Comparable<? super T> & Addible<? super T>> extends SinglyList<T>
{
protected boolean asc;
public SortedSinglyList(boolean asc)//构造空排序单链表 asc指定升/降序
{
}
public SortedSinglyList()//默认升序
{
super();
}
public SortedSinglyList(T[] values , boolean asc)//按值插入values数组元素
{
}
public SortedSinglyList(T[] values)//按值插入values数组元素,默认升序
{
super();
for (int i = 0 ; i < values.length ; i++)
this.insert(values[i]);
}
public SortedSinglyList(SortedSinglyList<T> list) //调用父类的深拷贝
{
super();
for (Node<T> p = list.head.next ; p != null ; p = p.next)
this.insert(p.data);
}
public SortedSinglyList(SortedSinglyList<T> list , boolean asc) //按值插入list所有元素
{
}
public void set(int i , T x)//不支持 覆盖并抛出异常
{
}
public Node<T> insert(int i ,T x)//不支持 覆盖并抛出异常
{
return null;
}
public Node<T> insert(T x)//插入x,按x大小顺序查找确定输入位置,插入在等值结点之后
{
Node<T> front = this.head , p = front.next;
while (p != null && x.compareTo(p.data) > 0)
{
front = p;
p = p.next;
}
front.next = new Node<T>(x , p);
return front.next;
}
}
6.创建PolySinglyList类继承SortedSinglyList
package Finalwork;
public class PolySinglyList<T extends Comparable<? super T> & Addible<? super T>> extends SortedSinglyList<T>
{
public Node<PolyNode> head;
public PolySinglyList()
{
this.head = new Node<PolyNode>();
}
public PolySinglyList(PolyNode[] values)
{
this();
Node<PolyNode> rear = this.head;
for (int i = 0 ; i < values.length ; i++)
{
if(values[i] != null)
{
rear.next = new Node<PolyNode>(values[i] , null);
rear = rear.next;
}
}
}
PolySinglyList<PolyNode> union(PolySinglyList<PolyNode> list)
{
PolySinglyList<PolyNode> C = new PolySinglyList<>();
Node<PolyNode> nodeC = C.head;
Node<PolyNode> p = this.head.next;
Node<PolyNode> q = list.head.next;
while (p != null)
{
nodeC.next = new Node<PolyNode>(new PolyNode(),null);
nodeC = nodeC.next;
while (q != null)
{
if(p.data.getExpo() == q.data.getExpo()) //比较指数是否相同
{
nodeC.data.setCoef(p.data.getCoef()+q.data.getCoef()); //系数赋值给c
nodeC.data.setExpo(p.data.getExpo()); //指数赋值给c
break;
}
q = q.next;
}
q = list.head.next;
p = p.next;
}
return C;
}
public String toString()
{
Node<PolyNode> p = this.head.next;
String str = "";
while (p != null)
{
str += p.data.toString();
p = p.next;
}
return str;
}
public boolean equals(Object obj)
{
return this == obj || obj instanceof PolySinglyList && this.head.next.equals(((PolySinglyList)obj).head.next);
}
public static void main(String[] args) {
PolyNode[] valuesA = new PolyNode[5];
valuesA[0] = new PolyNode("4x^1");
valuesA[1] = new PolyNode("3x^2");
valuesA[2] = new PolyNode("5x^3");
valuesA[3] = new PolyNode("2x^4");
valuesA[4] = new PolyNode("6x^5");
PolyNode[] valuesB = new PolyNode[5];
valuesB[0] = new PolyNode("2x^1");
valuesB[1] = new PolyNode("5x^2");
valuesB[2] = new PolyNode("8x^3");
valuesB[3] = new PolyNode("2x^4");
valuesB[4] = new PolyNode("3x^5");
PolySinglyList<PolyNode> listA = new PolySinglyList<>(valuesA);
PolySinglyList<PolyNode> listB = new PolySinglyList<>(valuesB);
System.out.println(listA.union(listB).toString());
boolean b = listA.equals(listB);
System.out.println(b);
}
}
7.创建Polynomial类
package Finalwork;
public class Polynomial {
private PolySinglyList<PolyNode> list;
public Polynomial()
{
this.list = new PolySinglyList<>();
}
public Polynomial(PolyNode terms[])
{
this.list = new PolySinglyList<>(terms);
}
public boolean equals(Object obj)
{
return this == obj || obj instanceof Polynomial && this.list.equals(((Polynomial)obj).list);
五、结果及分析
先创建节点数组valuesA valuesB,将节点放入线性表完成创建。测试Union方法后,运行成功完成多项式相加并ToString特定方法打印显示,测试equals方法也成功判断两多项式不同,显示结果为false,如果当两式相等,运行结果显示true。
六、总结与思考
问题提出:
单链表多项式相加存在,如果两个链表中只有一个链表有某一次项,另一个链表没有结果相加,之后出现了计算问题,该如何解决?
问题解决:
- 可以通过加入排序单链表星类,然后利用排序法将链表首先排好,然后紧接着用,逐步加入内容进结果列表中,如果有单一项的出现,将直接加入结果列表,不进行相加操作即可
2.也可以在相加功能中添加一些判断,能够使得当只有一项的时候可以直接加入结果链表中。