zoukankan      html  css  js  c++  java
  • 实验八

    学号 2019-2020-1823 《数据结构与面向对象程序设计》实验六报告

    班级: 1823

    姓名: 杨凯涵

    学号:20182321

    实验教师:王志强

    实验日期:2019年11月13日

    必修/选修: 必修

    1.实验内容

    实验一

    要求:参考教材PP16.1,完成链树LinkedBinaryTree的实现(getRight,contains,toString,preorder,postorder)
    用JUnit或自己编写驱动类对自己实现的LinkedBinaryTree进行测试,提交测试代码运行截图,要全屏,包含自己的学号信息
    课下把代码推送到代码托管平台

    首先,先把pp16.1的代码LinkedBinaryTree打下来

     public BTNode<T> root;
        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);
        }
    
        public T getRootElement() {
            if(root == null)
                throw new EmptyCollectionException("Get root operation failed.The tree is empty" );
            return root.getElement();
        }
         public LinkedBinaryTree<T> getLeft()
         {
             if(root == null)
                 throw new EmptyCollectionException("Get left operation faild. The tree is empty");
             LinkedBinaryTree<T> result = new LinkedBinaryTree<T>();
             result.root=root.getLeft();
             return result;
         }
         public T find (T target)
         {
             BTNode<T> node = null;
             if(root != null)
                 node = root.find(target);
             if(node == null)
                 throw new ElementNotFoundException("Find operation faild. No such element in tree");
             return node.getElement();
         }
         public int size()
         {
             int result =0;
             if(root!= null)
                 result = root.count();
             return result;
         }
         public ArrayList<T> inorder()
         {
             ArrayList<T> iter = new ArrayList<T>();
             if(root != null)
                 root.inorder(iter);
             return iter;
         }
        public ArrayList<T> levelorder() throws zhan.EmptyCollectionException {
            CircularArrayQueue<BTNode<T>> queue = new CircularArrayQueue<BTNode<T>>();
            ArrayList<T> iter = new ArrayList<T>();
            if (root != null)
            {
                queue.enqueue(root);
                while (!queue.isEmpty())
                {
                    BTNode<T> current = queue.dequeue();
                    iter.add(current.getElement());
                    if(current.getLeft()!= null)
                        queue.enqueue(current.getLeft());
                    if(current.getRight()!= null)
                        queue.enqueue(current.getRight());
    
                }
            }
            return iter;
        }
        public ArrayList<T> iterator()
        {
            return inorder();
        }
    

    接着按要求填充代码,首先是getright方法的

      public LinkedBinaryTree<T> getright()
        {
            if(root == null)
                throw new EmptyCollectionException("Get left operation faild. The tree is empty");
            LinkedBinaryTree<T> result = new LinkedBinaryTree<T>();
            result.root=root.getRight();
            return result;
        }
    

    与之前的getleft相同,接着我们补充contains代码

       public boolean contains (T target)
        {
            BTNode<T> now =null;
           now =root.find(target);
            if(root.getElement() == target)
                return true;
            else
                return false;
        }
    

    然后是isEmpty和toString

        public boolean isEmpty() {
            if (root == null)
                return true;
            else
                return false;
        }
    
        @Override
        public String toString() {
            return "LinkedBinaryTree{" +
                    "root=" + root +
                    '}';
        }
    

    最后是前序遍历和后序遍历

       public ArrayList<T> preoder(){
            ArrayList<T> iter = new ArrayList<T>();
            if(root != null)
                root.preorder(iter);
            return iter;
        }
        public ArrayList<T> postoder(){
            ArrayList<T> iter = new ArrayList<T>();
            if(root != null)
                root.postorder(iter);
            return iter;
        }
    

    接着我们再继续编写Test类来测试这个程序,最后得出结果

    实验二

    要求:基于LinkedBinaryTree,实现基于(中序,先序)序列构造唯一一棵二㕚树的功能,比如给出中序HDIBEMJNAFCKGL和后序ABDHIEJMNCFGKL,构造出附图中的树
    用JUnit或自己编写驱动类对自己实现的功能进行测试,提交测试代码运行截图,要全屏,包含自己的学号信息
    课下把代码推送到代码托管平台

    根据题目要求,我们编写了基于中序和先序的构建二叉树的代码(具体什么算法,我们会在下面讲到)

       public BTNode<Character> creattree(char[] preOrders, char[] inOrders)
        {
            if (preOrders.length == 0 || inOrders.length == 0) {
                return null;
            }
            BTNode<Character> tree = new BTNode<Character>(preOrders[0]);
            int index = search(0, inOrders.length, inOrders, tree.getElement());
            tree.setLeft(creattree(Arrays.copyOfRange(preOrders, 1, index + 1), Arrays.copyOfRange(inOrders, 0, index)));
            tree.setRight(creattree(Arrays.copyOfRange(preOrders, index + 1, preOrders.length),
                    Arrays.copyOfRange(inOrders, index + 1, inOrders.length)));
            return tree;
    
        }
    

    接着我们再通过dubug来验证是否二叉树已经构成

    再用前序输出它

     public void firstre(BTNode<T> biTree)
        {
            System.out.println(biTree.getElement()+"  (前序递归实现)");
            BTNode<T> leftTree = biTree.left;
            if(leftTree != null)
            {
                firstre(leftTree);
            }
            BTNode<T> rightTree = biTree.right;
            if(rightTree != null)
            {
                firstre(rightTree);
            }
        }
    

    实验三

    要求:自己设计并实现一颗决策树
    提交测试代码运行截图,要全屏,包含自己的学号信息
    课下把代码推送到代码托管平台

    根据教材上的提示,决策树就是以二叉树的形式建立其一颗“数”,通过问题的层层递进,最后输出结果。

    然后按照以上的思路,我们构建二叉树,再运行输出

    package experience8;
    
    import java.util.Scanner;
    
    public class decidetree {
        private LinkedBinaryTree<String> tree;
        public decidetree()
        {
            String e1 = "你是中国人吗?";
            String e2 = "你是电科院的吗?";
            String e3 = "你是外国留学生吗?" ;
            String e4 = "你太菜了";
            String e5 = "欢迎";
            String e6 = "给我滚!";
            String e7 = "别来";
            LinkedBinaryTree<String> n1,n2,n3,n4,n5,n6,n7;
    
            n4= new LinkedBinaryTree<String>(e4);
            n5=new LinkedBinaryTree<String>(e5);
            n2 = new LinkedBinaryTree<String>(e2,n4,n5);
            n6=new LinkedBinaryTree<String>(e6);
            n7 = new LinkedBinaryTree<String>(e7);
            n3 = new LinkedBinaryTree<String>(e3,n6,n7);
            n1=new LinkedBinaryTree<String>(e1,n2,n3);
            tree = n1;
        }
        public void diagnose()
        {
            Scanner scan = new Scanner(System.in);
            LinkedBinaryTree<String> current = tree;
            System.out.println("请接收我的审判");
            while (current.size()>1)
            {
                System.out.println(current.getRootElement());
                if(scan.nextLine().equalsIgnoreCase("N"))
                    current = current.getLeft();
                else
                    current = current.getright();
            }
            System.out.println(current.getRootElement());
    
        }
    
        public static void main(String[] args) {
            decidetree d = new decidetree();
            d.diagnose();
        }
    }
    

    最后的输出结果

    实验四

    要求 :输入中缀表达式,使用树将中缀表达式转换为后缀表达式,并输出后缀表达式和计算结果(如果没有用树,正常评分。如果用到了树,即使有小的问题,也酌情给满分)

    我们编写了如下代码(算法思路会在下面问题处讲解)

     static Stack<Character> op = new Stack<>();
    
        public static Float getv(char op, Float f1, Float f2){
            if(op == '+') return f2 + f1;
            else if(op == '-') return f2 - f1;
            else if(op  == '*') return f2 * f1;
            else if(op == '/') return f2 / f1;
            else return Float.valueOf(-0);
        }
    
        public static float calrp(String rp){
            Stack<Float> v = new Stack<>();
            char[] arr = rp.toCharArray();
            int len = arr.length;
            for(int i = 0; i < len; i++){
                Character ch = arr[i];
    
                // if is operand, push to the stack
                if(ch >= '0' && ch <= '9') v.push(Float.valueOf(ch - '0'));
    
                    // if is operator, calculate the result
                    // with top 2 operands in the stack,
                    // push the result into the stack
                else v.push(getv(ch, v.pop(), v.pop()));
            }
            return v.pop();
        }
    
        public static String getrp(String s) {
            char[] arr = s.toCharArray();
            int len = arr.length;
            String out = "";
    
            for (int i = 0; i < len; i++) {
                char ch = arr[i];
                if (ch == ' ') continue;
    
                // if is operand, add to
                // the output stream directly
                if (ch >= '0' && ch <= '9') {
                    out += ch;
                    continue;
                }
    
                //if is '(', push to the stack directly
                if (ch == '(') op.push(ch);
    
                //if is '+' or '-', pop the operator
                // from the stack until '(' and add to
                // the output stream
                //push the operator to the stack
                if (ch == '+' || ch == '-') {
                    while (!op.empty() && (op.peek() != '('))
                        out += op.pop();
                    op.push(ch);
                    continue;
                }
    
                //if is '*' or '/', pop the operator stack and
                // add to the output stream
                // until lower priority or '('
                //push the operator to the stack
                if (ch == '*' || ch == '/') {
                    while (!op.empty() && (op.peek() == '*' || op.peek() == '/'))
                        out += op.pop();
                    op.push(ch);
                    continue;
    

    输出如下所示

    3. 实验过程中遇到的问题和解决过程

    • 问题1:如何基于中序和先序来构建二叉树?
    • 问题1解决方法:基本的算法如下

    算法的思路是由先序来确定一个节点,而中序来确定左子树和右子数如
     前序:1 2 3 4 5 6 7 8 9 10

       中序:3 2 5 4 1 7 8 6 10 9

        

        <此算法默认优先处理左子树>

       (1)第一次:

          产生节点 1。(先序的第一个数肯定是节点)

          生成左子树(在中序中找到1,左为左子树,右为右子树)

              先序:2 3 4 5

              中序:3 2 5 4

          生成右子树

              前序:6 7 8 9 10

              中序:7 8 6 10 9

        (2)第二次

           产生节点 2(由左子树得来,故为第一次结点的左子树)。

           生成左子树

              前序:3

              中序:3

           生成右子树

              先序:4 5

              中序:5 4
              
    以此类推,来完成构建二叉树。

    • 问题2:如何来完成中缀转换成后缀
    • 问题2解决方法:

    算法思路:
    我做的是用栈来实现,利用等式的运算优先级来完成

    1.按次序读取中缀表达式的字符。

    2.读到一个操作数的时候,立即放入到输出中。

    3.读到操作符“+”,“-”,“*”,“/”,则从栈中弹出栈元素并输出,直到遇到优先级更低或者“(”的为止操作符为止(该元素不出栈)。

    4.读到操作符“(”,则直接把“(”压入栈中。

    5.读到操作符“)”,则从栈中弹出栈元素并输出,直到遇到第一个“(”为止。其中“(”不再添加到输出中,而是直接舍弃。

    6.当输入为空时,把栈里的操作符全部依次弹出并输出。

    例如输入:5+2(3(3-1*2+1))

    其他(感悟、思考等)

    • 对于学习数据结构来说,应该先想好算法再编写程序,否则上场就会相当懵逼
    • 树其实只是多个链表的一个集合,所以在处理树为问题时,其实就是一个多条链表集合的问题

    参考资料

    《Java程序设计与数据结构教程(第二版)》

    《Java程序设计与数据结构教程(第二版)》学习指导

  • 相关阅读:
    hyper-v启动虚拟机时提示“The application encountered an error while attempting to change the state of the machine ‘虚拟机名称'”如何处理?
    ubuntu下如何开机自动执行自定义脚本?
    centos下如何开放某个端口?
    linux都有哪些运行级别?
    linux内核在挂载ramdisk的过程中报错"RAMDISK: incomplete write (10739 != 32768)"如何处理?
    linux内核挂载根文件系统时报错”VFS: Cannot open root device "ram0" or unknown-block(0,0): error -6“如何处理?
    c代码审查软件
    项目管理术语表
    项目管理常用缩写
    MYSQL的读写分离主从延时问题
  • 原文地址:https://www.cnblogs.com/yangkaihan/p/11851143.html
Copyright © 2011-2022 走看看