zoukankan      html  css  js  c++  java
  • 20182316胡泊 实验8报告

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

    课程:《程序设计与数据结构》
    班级: 1823
    姓名: 胡泊
    学号:20182316
    实验教师:王志强
    实验日期:2019年
    必修/选修: 必修

    实验内容

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

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

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

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

    实验过程及结果

    • 参考书上代码,完成链树LinkedBinaryTree的实现(getRight,contains,toString,preorder,postorder),然后用junit测试。

    • 实现基于(中序,先序)序列构造唯一一棵二㕚树的功能,比如给出中序HDIBEMJNAFCKGL和后序ABDHIEJMNCFGKL,构造出附图中的树,用自己编写驱动类对自己实现的功能进行测试
      • 原理:将先序的第一个作为根,在中序中用根将其分开,根左边为左子树,右边则为右子树。
        image
      • 然后用通过递归来构造二叉树。

    • 自己设计并实现一颗决策树,构造一个二叉树,将每个节点中的数据提前设好,然后通过判断输入的条件来进入左子树或右子树。

    • 输入中缀表达式,使用树将中缀表达式转换为后缀表达式,并输出后缀表达式和计算结果
      • 步骤:
        • 按次序读取中缀表达式的字符。读到一个操作数的时候,立即放入到输出中。
        • 读到操作符“+”,“-”,“*”,“/”,则从栈中弹出栈元素并输出,直到遇到优先级更低或者“(”的为止操作符为止(该元素不出栈)。
        • 读到操作符“(”,则直接把“(”压入栈中。
        • 读到操作符“)”,则从栈中弹出栈元素并输出,直到遇到第一个“(”为止。其中“(”不再添加到输出中,而是直接舍弃。
        • 当输入为空时,把栈里的操作符全部依次弹出并输出。

    上传码云

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

    • 问题1:如何将二叉树以图形的形式打印出来,因为这样看着更直观,好看。
    • 问题1解决方案: 上网查询,看了几个,感觉用二维数组的比较简单并且好理解,代码如下:
    // 用于获得树的层数
        public static int getTreeDepth(TreeNode root) {
            return root == null ? 0 : (1 + Math.max(getTreeDepth(root.left), getTreeDepth(root.right)));
        }
    
    
        private static void writeArray(TreeNode currNode, int rowIndex, int columnIndex, String[][] res, int treeDepth) {
            // 保证输入的树不为空
            if (currNode == null) return;
            // 先将当前节点保存到二维数组中
            res[rowIndex][columnIndex] = String.valueOf(currNode.val);
    
            // 计算当前位于树的第几层
            int currLevel = ((rowIndex + 1) / 2);
            // 若到了最后一层,则返回
            if (currLevel == treeDepth) return;
            // 计算当前行到下一行,每个元素之间的间隔(下一行的列索引与当前元素的列索引之间的间隔)
            int gap = treeDepth - currLevel - 1;
    
            // 对左儿子进行判断,若有左儿子,则记录相应的"/"与左儿子的值
            if (currNode.left != null) {
                res[rowIndex + 1][columnIndex - gap] = "/";
                writeArray(currNode.left, rowIndex + 2, columnIndex - gap * 2, res, treeDepth);
            }
    
            // 对右儿子进行判断,若有右儿子,则记录相应的""与右儿子的值
            if (currNode.right != null) {
                res[rowIndex + 1][columnIndex + gap] = "\";
                writeArray(currNode.right, rowIndex + 2, columnIndex + gap * 2, res, treeDepth);
            }
        }
    
    
        public static void show(TreeNode root) {
            if (root == null) System.out.println("EMPTY!");
            // 得到树的深度
            int treeDepth = getTreeDepth(root);
    
            // 最后一行的宽度为2的(n - 1)次方乘3,再加1
            // 作为整个二维数组的宽度
            int arrayHeight = treeDepth * 2 - 1;
            int arrayWidth = (2 << (treeDepth - 2)) * 3 + 1;
            // 用一个字符串数组来存储每个位置应显示的元素
            String[][] res = new String[arrayHeight][arrayWidth];
            // 对数组进行初始化,默认为一个空格
            for (int i = 0; i < arrayHeight; i ++) {
                for (int j = 0; j < arrayWidth; j ++) {
                    res[i][j] = " ";
                }
            }
    
            // 从根节点开始,递归处理整个树
            // res[0][(arrayWidth + 1)/ 2] = (char)(root.val + '0');
            writeArray(root, 0, arrayWidth/ 2, res, treeDepth);
    
            // 此时,已经将所有需要显示的元素储存到了二维数组中,将其拼接并打印即可
            for (String[] line: res) {
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < line.length; i ++) {
                    sb.append(line[i]);
                    if (line[i].length() > 1 && i <= line.length - 1) {
                        i += line[i].length() > 4 ? 2: line[i].length() - 1;
                    }
                }
                System.out.println(sb.toString());
            }
        }
    }
    
    

    输出:

    感悟

    当我们学习新的知识,打新的代码时,总是会重复用到之前的知识,比如链表,栈等等,因此,打好基础十分的重要。

  • 相关阅读:
    HDU1506 Largest Rectangle in a Histogram(算竞进阶习题)
    洛谷P1073 最优贸易
    CH2101 可达性统计(算竞进阶习题)
    BZOJ1012 最大数maxnumber
    POJ 3764 The XOR Longest Path
    洛谷P4513 小白逛公园
    外边距叠加问题
    读JS高性能总结——DOM编程(一)
    DOM修改元素的方法总结
    DOM查找元素的方法总结
  • 原文地址:https://www.cnblogs.com/hp12138/p/11872993.html
Copyright © 2011-2022 走看看