实验八

学号 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<T> implements BinaryTreeADT<T>
{
    protected BTNode root;
    protected int modCount;

    public LinkedBinaryTree(){
        root = null;
    }

    public LinkedBinaryTree(T element){
        root = new BTNode<T>(element);
    }

    public LinkedBinaryTree(T element ,LinkedBinaryTree<T>left,LinkedBinaryTree<T> right){
        root = new BTNode<T>(element);
        root.setLeft(left.root);
        root.setRight(right.root);
    }

    @Override
    public T getRootElement() {
        return (T) root.getElement();
    }


    public LinkedBinaryTree<T> getLeft(){
        LinkedBinaryTree<T> result = new LinkedBinaryTree<T>();
        result.root = root.getLeft();

        return result;
    }

    public LinkedBinaryTree<T> getRight(){
        LinkedBinaryTree<T> result = new LinkedBinaryTree<T>();
        result.root = root.getRight();

        return result;
    }
/*
    public boolean contains(Object item){
        return getEntry((T) item) != null;
    }

    private BTNode<T> getEntry(T item){
        BTNode<T> 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> t = root;
        boolean ret;
        for(;t != null;){
            ret = aaa.equals(t.element);
            if (ret != true)
                ;


        }
    }
*/

    public T find(T target){
        BTNode<T> node = null;
        if(root != null)
            node = root.find(target);
        return node.getElement();
    }

    public void midIterator(BTNode<T> e){
        if (e != null){
            midIterator(e.left);
            System.out.print(e.getElement() + " ");
            midIterator(e.right);
        }
    }
    public void subIterator(BTNode<T> e){
        if (e != null) {
            subIterator(e.left);
            subIterator(e.right);
            System.out.print(e.getElement() + " ");
        }
    }

    public void prevIterator(BTNode<T> 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程序设计与数据结构教程(第二版)》学习指导
-  ...

posted on 2019-11-17 23:23  cistineup  阅读(199)  评论(0编辑  收藏  举报