20192306 2020-2021-1 《数据结构与面向对象程序设计》实验八报告

20192306 2020-2021-1 《数据结构与面向对象程序设计》实验八报告

课程:《程序设计与数据结构》
班级: 1923
姓名: 孙洪丽
学号: 20192306
实验教师:王志强
实验日期:2020年12月3日
必修/选修: 必修

1.实验内容

  • 参考教材PP16.1,完成链树LinkedBinaryTree的实现(getRight,contains,toString,preorder,postorder)
  1. 用JUnit或自己编写驱动类对自己实现的LinkedBinaryTree进行测试,提交测试代码运行截图,要全屏,包含自己的学号信息
  2. 课下把代码推送到代码托管平台
  • 基于LinkedBinaryTree,实现基于(中序,先序)序列构造唯一一棵二㕚树的功能,比如给出中序HDIBEMJNAFCKGL和后序ABDHIEJMNCFGKL,构造出附图中的树
  1. 用JUnit或自己编写驱动类对自己实现的功能进行测试,提交测试代码运行截图,要全屏,包含自己的学号信息
  2. 课下把代码推送到代码托管平台
  • 自己设计并实现一颗决策树
  1. 提交测试代码运行截图,要全屏,包含自己的学号信息
  2. 课下把代码推送到代码托管平台
  • 输入中缀表达式,使用树将中缀表达式转换为后缀表达式,并输出后缀表达式和计算结果(如果没有用树,正常评分。如果用到了树,即使有小的问题,也酌情给满分)
  1. 提交测试代码运行截图,要全屏,包含自己的学号信息

2.实验过程及结果

完成链树LinkedBinaryTree的实现

  • BTNode
import java.util.ArrayList;
public class BTNode<T>
{
    protected T element;
    protected BTNode<T> left, right;
    public BTNode (T element)
    {
        this.element = element;
        left = right = null;
    }
    public T getElement()
    {
        return element;
    }
    public void setElement (T element)
    {
        this.element = element;
    }
    public BTNode<T> getLeft()
    {
        return left;
    }
    public void setLeft (BTNode<T> left)
    {
        this.left = left;
    }
    public BTNode<T> getRight()
    {
        return right;
    }
    public void setRight (BTNode<T> right)
    {
        this.right = right;
    }
    public BTNode<T> find (T target) {
        BTNode<T> result = null;
        if (element.equals(target))
            result = this;
        else
        {
            if (left != null)
                result = left.find(target);
            if (result == null && right != null)
                result = right.find(target);
        }
        return result;
    }
    public int count() {
        int result = 1;
        if (left != null)
            result += left.count();
        if (right != null)
            result += right.count);
        return result;
    }
    public void inorder (ArrayList<T> iter) {
        if (left != null)
            left.inorder (iter);
        iter.add (element);
        if (right != null)
            right.inorder (iter);
    }
    public void preorder (ArrayList<T> iter) {
        iter.add (element);
        if (left != null)
            left.inorder (iter);
        if (right != null)
            right.inorder (iter);
    }
    public void postorder (ArrayList<T> iter) {
        if (left != null)
            left.inorder (iter);
        if (right != null)
            right.inorder (iter);
        iter.add (element);
    }
    public char print() {
        return (char) element;
    }
}
  • LinkedBinaryTree
import java.util.Iterator;
public class LinkedBinaryTree<T> implements BinaryTree<T> {
    public BTNode<T> root;//定义根结点
    public BTNode left;
    public BTNode right;
    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 {
        if (root == null)
            throw new Exception ("Get root operation "
                    + "failed. The tree is empty.");
        return root.getElement();
    }
    //先左子树
    public LinkedBinaryTree<T> getLeft() throws Exception {
        if (root == null)
            throw new Exception ("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 Exception {
        BTNode<T> node = null;
        if (root != null)
            node = root.find(target);
        if (node == null)
            throw new Exception("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 Iterator<T> inorder()
    {
        ArrayIterator<T> iter = new ArrayIterator<T>();
        if (root != null)
            root.inorder (iter);
        return  iter;
    }
    public Iterator<T> levelorder() throws EmptyCollectionException {
        LinkedQueue<BTNode<T>> queue = new LinkedQueue<BTNode<T>>();
        ArrayIterator<T> iter = new  ArrayIterator<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 Iterator<T> ArrayIterator()
    {
        return inorder();
    }
    //再右子树
    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;
    }
    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;
    }
    public boolean isEmpty() {
        if(root!=null)
            return false;
        else
            return true;
    }
    public String toString() {
        ArrayIterator<T> list = (ArrayIterator<T>) preorder();
        String result = "<top of Tree>\n";
        for(T i : list){
            result += i + "\t";
        }
        return result + "<bottom of Tree>";
    }
    public  Iterator<T> preorder() {
        ArrayIterator<T> list = new  ArrayIterator<>();
        if(root!=null)
            root.preorder(list);
        return list;
    }
    public  Iterator<T> postorder() {
        ArrayIterator<T> list = new  ArrayIterator<>();
        if(root!=null)
            root.postorder(list);
        return list;
    }
    @Override
    public Iterator<T> iterator() {
        return null;
    }
}

基于(中序,先序)序列构造唯一一棵二㕚树的功能

  • 扩展LinkedBinaryTree
public BTNode construct(char[] pre, char[] in) {
        if (pre.length == 0 || in.length == 0) {
            return null;
        }
        BTNode<Character> tree = new BTNode<Character>(pre[0]);
        int index = search(0, in.length, in, tree.getElement());
        tree.setLeft(construct(Arrays.copyOfRange(pre, 1, index + 1), Arrays.copyOfRange(in, 0, index)));
        tree.setRight(construct(Arrays.copyOfRange(pre, index + 1, pre.length),
                Arrays.copyOfRange(in, index + 1, in.length)));
        return tree;
    }
    public int search(int start, int end, char[] inOrders, char data) {
        for (int i = start; i < end; i++) {
            if (data == inOrders[i]) {
                return i;
            }
        }
        return -1;
    }
    public void preOrder(BTNode<T> Tree) {
        System.out.print(Tree.getElement() + " ");
        BTNode<T> leftTree = Tree.left;
        if (leftTree != null) {
            preOrder(leftTree);
        }
        BTNode<T> rightTree = Tree.right;
        if (rightTree != null) {
            preOrder(rightTree);
        }
    }
    public static void inOrder(BTNode tree) {
        if (tree == null)
            return;
        else {
            inOrder(tree.left);
            System.out.print(tree.print() + " ");
            inOrder(tree.right);
        }
    }

自己设计并实现一颗决策树

  • Decision
import java.util.Scanner;
public class Decision {
    private LinkedBinaryTree<String> tree;
    public Decision(){
        String e1 = "您知道王俊凯吗?";
        String e2 = "您知道我国的火星探测任务吗?";
        String e3 = "希望您多了解他,他很棒。";
        String e4 = "您知道它的主题曲《摘星少年》是由谁演唱的吗?";
        String e5 = "那没事了,希望您多多关注国家大事纪。";
        String e6 = "太好了,很高兴和您分享他。";
        String e7 = "是由王俊凯演唱的,希望您多多关注。";
        LinkedBinaryTree<String> n2,n3,n4,n5,n6,n7;
        n3 = new LinkedBinaryTree<String>(e3);
        n5 = new LinkedBinaryTree<String>(e5);
        n6 = new LinkedBinaryTree<String>(e6);
        n7 = new LinkedBinaryTree<String>(e7);
        n4 = new LinkedBinaryTree<String>(e4,n6,n7);
        n2 = new LinkedBinaryTree<String>(e2,n4,n5);
        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("Y"))
                current = current.getLeft();
            else
                current = current.getRight();
        }
        System.out.println(current.getRootElement());
    }
}
  • DecisionTest
public class DecisionTest  {
    public static void main(String[]args) throws Exception {
        Decision a = new Decision();
        a.diagose();
    }
}
  • 结果截图(各种逻辑合理,符合预期,决策树设计成功)




    码云

中缀表达式转换

  • 普通使用栈设计转换代码
import java.util.Stack;
public class Fix {
    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;
    }
}
  • 测试
import java.util.Scanner;
public class Test4 {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        System.out.println("请输入表达式:");
        String s = scan.nextLine();
        Fix fix = new Fix();
        System.out.println("后缀表达式为:\n"+Fix.getrp(s));
        System.out.println("计算结果为:\n"+fix.calrp(Fix.getrp(s)));
    }
}

其他(感悟、思考等)

  • 树是一个比较难掌握的数据结构,虽然上学期在离散课上接触过了,但知识掌握程度还停留在理论方面,真正代码实现的时候——特别是许多方法涉及递归算法的时候——我觉得还是很困难的,需要更多的实践去练习。

参考资料

posted @ 2020-12-09 15:20  20192306孙洪丽  阅读(303)  评论(0编辑  收藏  举报