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

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

    课程:《程序设计与数据结构》
    班级: 1823
    姓名: 赵沛凝
    学号:20182301
    实验教师:王志强
    实验日期:2019年11月11日
    必修/选修: 必修

    1.实验内容

    • 参考教材PP16.1,完成链树LinkedBinaryTree的实现(getRight,contains,toString,preorder,postorder),用JUnit或自己编写驱动类对自己实现的LinkedBinaryTree进行测试。
    • 基于LinkedBinaryTree,实现基于(中序,先序)序列构造唯一一棵二㕚树的功能,比如给出中序HDIBEMJNAFCKGL和先序ABDHIEJMNCFGKL,构造出附图中的树,用JUnit或自己编写驱动类对自己实现的功能进行测试。
    • 自己设计并实现一颗决策树并完成测试。
    • 输入中缀表达式,使用树将中缀表达式转换为后缀表达式,并输出后缀表达式和计算结果

    2. 实验过程及结果

    第一个:

    • 对这几个方法进行补充(getRight,contains,toString,preorder,postorder),代码如下:
    • getRight
    public LinkedBinaryTree<T> getRight() throws Exception {
            if (root == null)
                throw new Exception ("Get Right operation "
                        + "failed. The tree is empty.");
            LinkedBinaryTree<T> result = new LinkedBinaryTree<T>();
            result.root = root.getRight();
    
            return result;
        }
    
    • contains
    public boolean contains (T target) throws Exception {
            BTNode<T> node = null;
            boolean result = true;
            if (root != null)
                node = root.find(target);
            if(node == null)
                result = false;
            return result;
        }
    
    • preorder
    public  Iterator<T> preorder() {
            ArrayIterator<T> list = new  ArrayIterator<>();
    
            if(root!=null)
                root.preorder(list);
            return list;
        }
    
    • toString
    public String toString() {
            ArrayIterator<T> list = (ArrayIterator<T>) preorder();
            String result = "<top of Tree>
    ";
            for(T i : list){
                result += i + "	";
            }
            return result + "<bottom of Tree>";
        }
    
    • postorder
    public  Iterator<T> postorder() {
            ArrayIterator<T> list = new  ArrayIterator<>();
    
            if(root!=null)
                root.postorder(list);
            return list;
        }
    

    第二个

    • 运用先序、中序建立一个脑中的图像并不难,如下:
    • 但是在代码上就容易出现问题,在借鉴以及自我理解的基础上,搞了出来:
    public static LinkedBinaryTree returnTree(char[] in, char[] pre)
        {
            LinkedBinaryTree tree;
            if(pre.length == 0 || in.length == 0 || pre.length != in.length){ // 终止递归的条件
                tree =  new LinkedBinaryTree();
            }
            else {
                int x = 0;
                while (in[x] != pre[0]) {   // 找到根结点
                    x++;
                }
    
                char[] inLeft = new char[x];       // 根结点的左边为左子树,创建新的数组
                char[] preLeft = new char[x];
                char[] inRight = new char[in.length - x - 1];       // 根结点的右边为右子树,创建新的数组
                char[] preRight = new char[pre.length - x - 1];
    
                for (int y = 0; y < in.length; y++) {   // 把原数组的数存入新的数组当中
                    if (y < x) {
                        inLeft[y] = in[y];
                        preLeft[y] = pre[y + 1];
                    } else if (y > x) {
                        inRight[y - x - 1] = in[y];
                        preRight[y - x - 1] = pre[y];
                    }
                }
                LinkedBinaryTree left = returnTree(inLeft, preLeft);   // 左子树递归调用
                LinkedBinaryTree right = returnTree(inRight, preRight); // 右子树递归调用
                tree = new LinkedBinaryTree(pre[0], left,right);
            }
            return tree;//HDIBEMJNAFCKGL;ABDHIEJMNCFGKL
        }
    
    • 本来我只弄了一个后续遍历的输出,但是看到大家都做出了树,于是又自我学习,详见问题1.
    • 最后还是出现了树哦!

    第三个

    • 首先要设计决策树的脑图,构建思路,如图所示:

    • 从左向右,从上向下进行编号
    • 利用如下代码进行构建:
         LinkedBinaryTree<String>n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15;
            n15 = new LinkedBinaryTree<String>(e15);
            n14 = new LinkedBinaryTree<String>(e14);
            n11 = new LinkedBinaryTree<String>(e11,n14,n15);
            n12 = new LinkedBinaryTree<String>(e12);
            n13 = new LinkedBinaryTree<String>(e13);
            n7 = new LinkedBinaryTree<String>(e7,n12,n13);
            n8 = new LinkedBinaryTree<String>(e8);
            n9 = new LinkedBinaryTree<String>(e9);
            n5 = new LinkedBinaryTree<String>(e5,n8,n9);
            n10 = new LinkedBinaryTree<String>(e10);
            n6 = new LinkedBinaryTree<String>(e6,n10,n11);
            n4 = new LinkedBinaryTree<String>(e4);
            n2 = new LinkedBinaryTree<String>(e2,n4,n5);
            n3 = new LinkedBinaryTree<String>(e3,n6,n7);
            tree = new LinkedBinaryTree<String>(e1,n2,n3);
    
    • 使用如下方法进行判断
        public void diagose() throws Exception {
            Scanner scan = new Scanner(System.in);
            LinkedBinaryTree<String>current = tree;
            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 class Postfix {
    
        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(ch >= '0' && ch <= '9') v.push(Float.valueOf(ch - '0'));
                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(ch >= '0' && ch <= '9') {
                    out+=ch;
                    continue;
                }
    
                if(ch == '(') op.push(ch);
    
                if(ch == '+' || ch == '-'){
                    while(!op.empty() && (op.peek() != '('))
                        out+=op.pop();
                    op.push(ch);
                    continue;
                }
    
    
                if(ch == '*' || ch == '/'){
                    while(!op.empty() && (op.peek() == '*' || op.peek() == '/'))
                        out+=op.pop();
                    op.push(ch);
                    continue;
                }
    
                if(ch == ')'){
                    while(!op.empty() && op.peek() != '(')
                        out += op.pop();
                    op.pop();
                    continue;
                }
            }
            while(!op.empty()) out += op.pop();
            return out;
        }
    
        public static void main(String[] args){
            System.out.println("输入中缀表达式:");
            Scanner scan=new Scanner(System.in);
            String exp=scan.nextLine();
            System.out.println("后缀表达式为:");
            System.out.println(getrp(exp));
            System.out.println("结果为:");
            System.out.println(calrp(getrp(exp)));
        }
    
    }
    
    • 再有对于使用树进行中缀转后缀,其实它可以定义为表达树,

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

    • 问题1:如何真的画出一棵树呢?
    • 问题1解决方案:
    • 这个代码很复杂,需要仔细理解
        public String toString() {
            UnorderedListADT<BinaryTreeNode<T>> nodes = new ArrayListUnordered<BinaryTreeNode<T>>();
            UnorderedListADT<Integer> levelList = new ArrayListUnordered<Integer>();
    
            BinaryTreeNode<T> current = null;
            String result = "";
            int printDepth = this.getHeight();
            int possibleNodes = (int) Math.pow(2, printDepth + 1);
            int countNodes = 0;
    
            nodes.addToRear(root);
            Integer currentLevel = 0;
            Integer previousLevel = -1;
            levelList.addToRear(currentLevel);
    
            while (countNodes < possibleNodes) {
                countNodes = countNodes + 1;
                try {
                    current = nodes.removeFirst();
                } catch (EmptyCollectionException e) {
                    e.printStackTrace();
                }
                try {
                    currentLevel = levelList.removeFirst();
                } catch (EmptyCollectionException e) {
                    e.printStackTrace();
                }
                if (currentLevel > previousLevel) {
                    result = result + "
    
    ";
                    previousLevel = currentLevel;
                    for (int j = 0; j < ((Math.pow(2, (printDepth - currentLevel))) - 1); j++)
                        result = result + " ";
                } else {
                    for (int i = 0; i < (Math.pow(2, (printDepth - currentLevel + 1)) - 1); i++) {
                        result = result + " ";
                    }
                }
                if (current != null) {
                    result = result + (current.getElement()).toString();
                    nodes.addToRear(current.getLeft());
                    levelList.addToRear(currentLevel + 1);
                    nodes.addToRear(current.getRight());
                    levelList.addToRear(currentLevel + 1);
                } else {
                    nodes.addToRear(null);
                    levelList.addToRear(currentLevel + 1);
                    result = result + " ";
                }
            }
            return result;
        }
    
    • 问题2:决策树很容易理解,那么表达树是什么意思呢?详见链接1

    • 问题2解决方案:

    • 前缀表达式(前序遍历):/+A*CBD

    • 中缀表达式(中序遍历):A+B*C/D

    • 后缀表达式(后序遍历):ACB*+D/

    • 代码如下:

    public class ExprTree {
        //最后访问头结点
        public BinaryTreeNode buildExprTree(char postfixExpr[],int size){
            LinkedList<BinaryTreeNode> stack=new LinkedList();
            BinaryTreeNode node=null;
            for(int i=0;i<size;i++){
                if(isOperateNum(postfixExpr[i])){
                    node=new BinaryTreeNode();
                    node.setLeft(null);
                    node.setRight(null);
                    node.setData(postfixExpr[i]);
                    stack.push(node);
                }else{
                    BinaryTreeNode leftChild=stack.pop();
                    BinaryTreeNode rightChild=stack.pop();
                    node =new BinaryTreeNode();
                    node.setLeft(leftChild);
                    node.setRight(rightChild);
                    node.setData(postfixExpr[i]);
                    stack.push(node);
                }
            }
            return stack.getLast(); 
        }
        
        //判断是否是操作数
        private boolean isOperateNum(char c){
            if(c=='/'||c=='+'||c=='*'||c=='-'){
                return false;
            }
            return true;
        }
    
    }
    

    其他(感悟、思考等)

    在学习树的各种时,可以说是非常难的,但是看到更加优秀的人,创造出更加优秀的树,自己也要不断努力

    参考资料

  • 相关阅读:
    网页居中的问题
    棋盘覆盖
    可变宽度的圆角框
    多线程编辑问题
    实验五 Web项目开发
    实验三 一个标准的Windows应用程序
    【语言处理与Python】1.2将文本当作词链表
    【语言处理与Python】1.5自动理解自然语言
    【语言处理与Python】1.1文本和单词
    【语言处理与Python】1.3计算语言:简单的统计
  • 原文地址:https://www.cnblogs.com/zhaopeining/p/11878546.html
Copyright © 2011-2022 走看看