zoukankan      html  css  js  c++  java
  • 20182320 2019-2020-1 《数据结构与面向对象程序设计》实验8报告

    20182320 2019-2020-1 《数据结构与面向对象程序设计》实验8报告

    课程:《程序设计与数据结构》

    班级: 1823

    姓名: 郑力元

    学号:20182320

    实验教师:王志强

    实验日期:2019年11月11日

    必修/选修: 必修

    1.实验内容

    1.1

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

    1.2

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

    1.3

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

    1.4

    输入中缀表达式,使用树将中缀表达式转换为后缀表达式,并输出后缀表达式和计算结果(如果没有用树,正常评分。如果用到了树,即使有小的问题,也酌情给满分)
    提交测试代码运行截图,要全屏,包含自己的学号信息

    2. 实验过程及结果

    2.1

    第一步:补充实现书上的LinkedBinaryTree类,它需要编写一个BinaryTree接口,一个节点类,两个异常类,才能完整实现LinkedBinaryTree。

    代码如下,这里将书上的ArrayIterator换成了ArrayList:

    public class LinkedBinaryTree<T> implements BinaryTree<T>
    {
        protected 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() throws Exception, EmptyCollectionException {
            if (root == null)
                throw new EmptyCollectionException ("Get root operation "
                        + "failed. The tree is empty.");
    
            return root.getElement();
        }
    
        public LinkedBinaryTree<T> getLeft() throws Exception, EmptyCollectionException {
            if (root == null)
                throw new EmptyCollectionException ("Get left operation "
                        + "failed. The tree is empty.");
    
            LinkedBinaryTree<T> result = new LinkedBinaryTree<T>();
            result.root = root.getLeft();
    
            return result;
        }
    
        public T find (T target) throws ElementNotFoundException {
            BTNode<T> node = null;
    
            if (root != null)
                node = root.find(target);
    
            if (node == null)
                throw new ElementNotFoundException("Find operation failed. "
                        + "No such element in tree.");
    
            return node.getElement();
        }
    
    //返回大小
        public int size()
        {
            int result = 0;
    
            if (root != null)
                result = root.count();
    
            return result;
        }
    
         public LinkedBinaryTree<T> getRight() throws Exception, EmptyCollectionException {
             if (root == null)
                 throw new EmptyCollectionException ("Get left operation "
                         + "failed. The tree is empty.");
    
             LinkedBinaryTree<T> result = new LinkedBinaryTree<T>();
             result.root = root.getRight();
    
             return result;
         }
    
         public boolean contains (T target) {
            if (root.find(target)==null){
                return false;
            }
            else {
                return true;
            }
         }
    
         public boolean isEmpty() {
            if (root==null){
                return true;
            }
            else {
                return false;
            }
         }
    
    //先序遍历
        public ArrayList<T> preorder() {
            ArrayList<T> iter = new ArrayList<T>();
    
            if (root != null)
                root.preorder (iter);
    
            return iter;
        }
    
    //后续遍历
        public ArrayList<T> postorder() {
            ArrayList<T> iter = new ArrayList<T>();
    
            if (root != null)
                root.postorder (iter);
    
            return iter;
        }
         public String toString() {
             return super.toString();
         }
    }
    

    第二步:编写测试代码,运行

    2.2

    第一步:修改上面的LinkedBinaryTree方法,将先序、中序和后序遍历都改成返回字符串,同时加入能够从上到下构造二叉树的方法:

        public int findIndexInArray(char[] a, char x, int begin, int end) {
            for(int i=begin;i<=end;i++) {
                if(a[i] == x) {
                    return i;
                }
            }
            return -1;
        }
    
    
        public void initTree(char[] preOrder, char[] inOrder) {
            this.root = this.initTree(preOrder, 0, preOrder.length-1, inOrder, 0, inOrder.length-1);
        }
    
        public BTNode initTree(char[] preOrder, int start1, int end1, char[] inOrder, int start2, int end2) {
            if(start1 > end1 || start2 > end2) {
                return null;
            }
            //通过前序找到根结底
            char rootData = preOrder[start1];
            BTNode<Character> head = new BTNode(rootData);
            //从中序遍历里找到根结点所在的位置
            int rootIndex = findIndexInArray(inOrder, rootData, start2, end2);
            //offSet代表左子树的长度-1(也就是中序遍历中,左子树最后一个元素的下标)
            int offSet = rootIndex - start2 - 1;
            //递归构建左子树
            BTNode left = initTree(preOrder, start1+1, start1+1+offSet, inOrder, start2, start2+offSet);
            //递归构建右子树
            BTNode right = initTree(preOrder, start1+offSet+2, end1, inOrder, rootIndex+1, end2);
            head.left = left;
            head.right = right;
            return head;
        }
    

    第二步:编写测试代码,运行,这里用后续遍历检验是否正常构建二叉树

    2.3

    第一步:编写好节点类和决策树类(包含主方法和构建与运行决策树的方法)

        public static void buildDTree(){
            root=new BTNode("大力帅吗?y/n");
            BTNode<String> temp=root;
            temp.left=new BTNode<>("你错了。");
            temp.right=new BTNode<>("大力聪明吗?y/n");
    
            temp=temp.right;
            temp.left=new BTNode<>("你错了。");
            temp.right=new BTNode<>("大力强吗?y/n");
    
            temp=temp.right;
            temp.left=new BTNode<>("你错了。");
            temp.right=new BTNode<>("你说的都对了。");
        }
    
        public static void runDTree(BTNode root){
            System.out.println(root.element);
            if (root.left==null||root.right==null){
                return;
            }
            while (true){
                stringTokenizer=new StringTokenizer(scanner.nextLine());
                String string=stringTokenizer.nextToken();
    
                if (string.equals("y")){
                    runDTree(root.right);
                    break;
                }
                else if (string.equals("n")){
                    runDTree(root.left);
                    break;
                }
                else {
                    System.out.println("输入错误!重新输入。");
                }
            }
        }
    

    第二步:运行


    2.4

    第一步:编写中缀转后缀的类(包括主方法):

    public static String infixToSuffix(String infix) {
            Stack<Character> stack = new Stack<Character>();
            String suffix = "";
            int length = infix.length();
            for (int i = 0; i < length; i++) {
                Character temp;
                char c = infix.charAt(i);
                switch (c) {
                    // 忽略空格
                    case ' ':
                        break;
                    // 碰到'(',push到栈
                    case '(':
                        stack.push(c);
                        break;
                    // 碰到'+''-',将栈中所有运算符弹出,送到输出队列中
                    case '+':
                    case '-':
                        while (stack.size() != 0) {
                            temp = stack.pop();
                            if (temp == '(') {
                                stack.push('(');
                                break;
                            }
                            suffix += " " + temp;
                        }
                        stack.push(c);
                        suffix += " ";
                        break;
                    // 碰到'*''/',将栈中所有乘除运算符弹出,送到输出队列中
                    case '*':
                    case '/':
                        while (stack.size() != 0) {
                            temp = stack.pop();
                            if (temp == '(' || temp == '+' || temp == '-') {
                                stack.push(temp);
                                break;
                            } else {
                                suffix += " " + temp;
                            }
                        }
                        stack.push(c);
                        suffix += " ";
                        break;
                    // 碰到右括号,将靠近栈顶的第一个左括号上面的运算符全部依次弹出,送至输出队列后,再丢弃左括号
                    case ')':
                        while (stack.size() != 0) {
                            temp = stack.pop();
                            if (temp == '(')
                                break;
                            else
                                suffix += " " + temp;
                        }
                        // suffix += " ";
                        break;
                    //如果是数字,直接送至输出序列
                    default:
                        suffix += c;
                }
            }
    
            //如果栈不为空,把剩余的运算符依次弹出,送至输出序列。
            while (stack.size() != 0) {
                suffix += " " + stack.pop();
            }
            return suffix;
        }
    

    第二步:运行

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

    问题1:

    原本是想基于LinkedBinaryTree的构造二叉树的方法,完成8.2的二叉树的构建,但是发现LinkedBinaryTree的原本构造方法是自下而上构造二叉树的,然而已知的先序和中序遍历能确定的根是在二叉树的最顶端

    问题1解决:

    自己加了一个自上而下的构造二叉树的方法,实现功能。

    其他(感悟、思考等)

    这一次实验主要考察我们对树的结构以及其特点的掌握,涉及到了树的构建、通过前序与中序构造树还有决策树的构建。虽然在最后一个中缀转后缀中我没能用树的结构来实现,但是通过栈和队列两种线性结构来实现这个功能难度依然不小,花费时间较多。这些编程实践能够让我们对一些经典的数据结构有更深刻的理解。

    参考资料

  • 相关阅读:
    linux开发板出现Read-only file system的解决办法
    nginx源码分析之网络初始化
    nginx源码分析之hash的实现
    hdu4833 Best Financing(DP)
    PHP读取office word文档内容及图片
    nginx+uwsgi+bottle python服务器部署
    创建、托管和浏览文档
    python非官方扩展库
    simplexml_load_string 转换xml为数组
    PHPExcel 导出数据(xls或xlsx或csv)- 助手类(函数)
  • 原文地址:https://www.cnblogs.com/leonzheng/p/11869422.html
Copyright © 2011-2022 走看看