学号 20182334 《数据结构与面向对象程序设计》实验八报告
课程:《程序设计与数据结构》
班级: 1823
姓名: 姬旭
学号:20182334
实验教师:王志强
实验日期:2019年11月11日
必修/选修: 必修
1.实验内容
实验八-1-实现二叉树
参考教材PP16.1,完成链树LinkedBinaryTree的实现(getRight,contains,toString,preorder,postorder)
实验八-2-中序先序序列构造二叉树(例子中的后序为先序)
基于LinkedBinaryTree,实现基于(中序,先序)序列构造唯一一棵二㕚树的功能,比如给出中序HDIBEMJNAFCKGL和后序ABDHIEJMNCFGKL,构造出附图中的树
用JUnit或自己编写驱动类对自己实现的功能进行测试,提交测试代码运行截图,要全屏,包含自己的学号信息
课下把代码推送到代码托管平台
实验八-树-3-决策树
自己设计并实现一颗决策树
提交测试代码运行截图,要全屏,包含自己的学号信息
课下把代码推送到代码托管平台
实验八-4-表达式树
输入中缀表达式,使用树将中缀表达式转换为后缀表达式,并输出后缀表达式和计算结果(如果没有用树,正常评分。如果用到了树,即使有小的问题,也酌情给满分)
提交测试代码运行截图,要全屏,包含自己的学号信息
2. 实验过程及结果
- 实验一即选择性理解书上的代码,重点理解先序与后序中序得细微区别。
完成了LinkedBinaryTree的实现,并且用了很多方法:
package LinkedBinaryTree;
public class LinkedBinaryTree implements BinaryTreeADT
{
protected BTNode root;
protected int modCount;
public LinkedBinaryTree(){
root = null;
}
public LinkedBinaryTree(T element){
root = new BTNode(element);
}
public LinkedBinaryTree(T element ,LinkedBinaryTreeleft,LinkedBinaryTree right){
root = new BTNode(element);
root.setLeft(left.root);
root.setRight(right.root);
}
@Override
public T getRootElement() {
return (T) root.getElement();
}
public LinkedBinaryTree getLeft(){
LinkedBinaryTree result = new LinkedBinaryTree();
result.root = root.getLeft();
return result;
}
public LinkedBinaryTree getRight(){
LinkedBinaryTree result = new LinkedBinaryTree();
result.root = root.getRight();
return result;
}
/*
public boolean contains(Object item){
return getEntry((T) item) != null;
}
private BTNode getEntry(T item){
BTNode t = root;
int ret;
//从根节点开始遍历
for (;t != null;){
ret = (item.element).equals(t.element);
if (ret != true)
t = t.left;
else if (ret > 0)
t = t.right;
else
return t;
}
return null;
}
*/
/*
public boolean contains1(T aaa){
BTNode t = root;
boolean ret;
for(;t != null;){
ret = aaa.equals(t.element);
if (ret != true)
;
}
}
*/
public T find(T target){
BTNode node = null;
if(root != null)
node = root.find(target);
return node.getElement();
}
public void midIterator(BTNode e){
if (e != null){
midIterator(e.left);
System.out.print(e.getElement() + " ");
midIterator(e.right);
}
}
public void subIterator(BTNode e){
if (e != null) {
subIterator(e.left);
subIterator(e.right);
System.out.print(e.getElement() + " ");
}
}
public void prevIterator(BTNode e){
if (e != null) {
System.out.print(e.getElement() + " ");
prevIterator(e.left);
prevIterator(e.right);
}
}
public int size(){
int result = 0 ;
if(root != null)
result = root.count();
return result;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public boolean contains(T targetElement) {
return false;
}
/*
@Override
public boolean contains(Object targetElement) {
return false;
}
*/
@Override
public Iterable PreOrder() {
return null;
}
@Override
public Iterable PostOrder() {
return null;
}
}
- 实验二运用两次递归,顺序为常规顺序,先右后左。
public class Exper_2{
private Node root;
public Node creat(String []preOrder,int pstart,int pend,String []inOrder ,int instart,int inend){
if(pstart > pend || instart > inend){
return null;
}
String rootData = preOrder[pstart];
Node root = new Node(rootData);
int rootIndex = findIndexInArray(inOrder,rootData,instart,inend);
int xiabiao = rootIndex - instart - 1;
//左
Node left = creat(preOrder,pstart+1,pstart+xiabiao+1,inOrder,instart,instart+xiabiao);
//右
Node right = creat(preOrder,pstart + xiabiao + 2,pend,inOrder,rootIndex+1,inend);
root.setLeft(left);
root.setright(right);
return root;
}
private int findIndexInArray(String[] inOrder, String rootData, int instart, int inend) {
for (int i = instart; i <= inend; i++) {
if(inOrder[i].equals(rootData) ){
return i;
}
}
return -1;
}
public void subIterator(Node e){
if (e != null) {
subIterator(e.getLeft());
subIterator(e.getright());
System.out.print(e.getData() + " ");
}
}
}
上面代码中creat方法很巧妙,希望能帮助到很多人,用了递归,传入数组和首地址和尾地址。
实验3建立决策二叉树,方法简单,只需存入你想出现得字符串,在运用其中相应得构造方法,即可完成建树,再使用几个if判断左移右移得方法,即可完成决策二叉树得建立。
实验4,将先序转为后序存起来遇到很大麻烦,起初不知道如何操作才能使数字元素按顺序排好。经搜索得,可将数字与运算符分别存入两个栈中,读到运算符时,比较该运算符与栈顶运算符得先后顺序,选择放入数字栈里还是存入运算符栈里。
3. 实验过程中遇到的问题和解决过程
问题1:在完成实验2的过程中发现,自己对于中中后序的理解还是不够深入,无法通过三者的联系发现规律。
- 问题1解决方案:以此实验为例,首先根据前序,找到其根节点,再转向中序,中序找到该节点,节点前就是左二叉树,节点右就是有二叉树,先查找左二叉树,
问题2:在实验四中,如图所示,起初没有声明对象直接将所有bottom写入栈中,使得盛放运算符的栈不合理。
问题2解决方案:将你想存入的内容写成一个实例化结点,将该节点存栈,否则存入button节点其所自带的next也会保留下来,输出时,一个个next将所有的内容输出出来。
- 调试代码时,这几段代码屡屡报错,经单步调试后发现原因。
调试发现原因,这几段代码涉及数据存入取出,而数据取出的时候,也应进行相应的类型转换。
问题3:在第二个实验过程中,不明白如何通过两个序列创建新的序列。
- 问题3解决方案:通过之前的学习,知道创建树一定是要用递归的,至于怎么用递归,每种树有每种的方法。在这种通过两个序列变成另外一个序列的实验中,我发现利用Test传来数组和它的首地址包括尾地址,前序中序都传来,两个结合使用,最后完成的很好。
以下是creat方法:
public Node creat(String []preOrder,int pstart,int pend,String []inOrder ,int instart,int inend){
if(pstart > pend || instart > inend){
return null;
}
String rootData = preOrder[pstart];
Node root = new Node(rootData);
int rootIndex = findIndexInArray(inOrder,rootData,instart,inend);
int xiabiao = rootIndex - instart - 1;
//左
Node left = creat(preOrder,pstart+1,pstart+xiabiao+1,inOrder,instart,instart+xiabiao);
//右
Node right = creat(preOrder,pstart + xiabiao + 2,pend,inOrder,rootIndex+1,inend);
root.setLeft(left);
root.setright(right);
return root;
}
其他(感悟、思考等)
学习java不易,学习数据结构同样不易。无论是哪种语言,都要经历自学和不断摸索,当然摸索的过程是苦涩的,是很烦人的,是崩溃的,是无助的,但当自己把问题解决了之后,你会发现自己学到了很多知识,是曾经的自己所无法匹敌的,也是自己所期待的。当所有问题都解决之后,永远会有新的问题出现,继续折磨你,如果说你感到无事可做,那种感觉就和死了一样,很恐怖,也会让人堕落。人的一生都是在不断创造问题解决问题,再创造问题的过程中不断前进,否定之否定,会让我们更强。摸索的过程是苦涩的,是很烦人的,是崩溃的,是无助的,但当自己把问题解决了之后,你会发现自己学到了很多知识,是曾经的自己所无法匹敌的,也是自己所期待的。
参考资料
- 《Java程序设计与数据结构教程(第二版)》
- 《Java程序设计与数据结构教程(第二版)》学习指导
- ...