博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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

课程:《程序设计与数据结构》
班级: 2023
姓名: 何锐
学号:20202304
实验教师:王志强
实验日期:2021年11月18日

必修/选修: 必修

一、实验内容

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

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

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

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

二、实验过程及结果

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

(1)树节点:

public class TreeNode {
    private Object value;//节点值
    private TreeNode leftChild;//左子树
    private TreeNode rightChild;//右子树

    @Override
    public String toString() {
        return "树节点{" +
                "数值=" + value +
                ", 左子树为" + leftChild +
                ", 右子树为" + rightChild +
                '}';
    }

    public TreeNode(Object value) {
        this.value = value;
    }

    public TreeNode(Object value, TreeNode leftChild, TreeNode rightChild) {
        this.value = value;
        this.leftChild = leftChild;
        this.rightChild = rightChild;
    }

    public Object getValue() {
        return value;
    }

    public void setValue(Object value) {
        this.value = value;
    }

    public TreeNode getLeftChild() {
        return leftChild;
    }

    public void setLeftChild(TreeNode leftChild) {
        this.leftChild = leftChild;
    }

    public TreeNode getRightChild() {
        return rightChild;
    }

    public void setRightChild(TreeNode rightChild) {
        this.rightChild = rightChild;
    }
}

(2)二叉树:

public class BinaryTree {
    private TreeNode root;//根节点

    public BinaryTree() {
    }
    public BinaryTree(TreeNode root){
        this.root = root;
    }

    //判断是否为空
    public boolean isEmpty() {
        return root == null;
    }
    //结点个数
    public int size() {
        System.out.print("二叉树结点个数:");
        return this.size(root);
    }
    private int size(TreeNode root) {
        if(root == null){
            return 0;
        }else {
            //获取左子树结点数
            int lf = this.size(root.getLeftChild());
            //获取右子树结点数
            int ri = this.size(root.getRightChild());
            //相加并+1
            return lf+ri+1;
        }
    }
    //高度
    public int getHeight() {
        System.out.print("二叉树的高度是:");
        return this.getHeight(root);
    }
    private int getHeight(TreeNode root) {
        if (root == null) {
            return 0;
        } else{
            //获取左子树的高度
            int lf = this.getHeight(root.getLeftChild());
            //获取右子树的高度
            int ri = this.getHeight(root.getRightChild());
            //返回左子树、右子树较大高度并+1
            return lf>ri?lf+1:ri+1;
        }
    }
    //获取右子树
    public TreeNode getRight(TreeNode root){
        return root.getRightChild();
    }
    //获取左子树
    public TreeNode getLeft(TreeNode root){
        return root.getLeftChild();
    }

    public boolean contains(Object value){
        if (this.findKey(value,root)== null) {
            return false;
        }else {
            return true;
        }

    }
    private TreeNode findKey(Object value, TreeNode root) {
        if (root == null){
            return null;

        }else if (root !=null && root.getValue() == value){
            return root;
        }else {
            //递归体
            TreeNode node1 = this.findKey(value, root.getLeftChild());
            TreeNode node2 = this.findKey(value, root.getRightChild());
            if (node1 != null && node1.getValue() == value){
                return node1;
            }else if (node2 != null && node2.getValue() == value){
                return node2;
            }else {
                return null;
            }
        }
    }
    public  void preorder(){
    System.out.println("先序遍历:");
    preorder(root);
        System.out.println("");
    }
    private void preorder(TreeNode root) {
        if(root != null){
            System.out.print(root.getValue()+" ");
        preorder(root.getLeftChild());
        preorder(root.getRightChild());

        }
    }

    public void postorder(){
    System.out.println("后序遍历:");
    postorder(root);
        System.out.println("");
    }
    private void postorder(TreeNode root) {
        if (root != null) {
            this.postorder(root.getLeftChild());
            this.postorder(root.getRightChild());
            System.out.print(root.getValue() + " ");
        }
    }
}

(3)测试代码:

import java.util.TreeMap;

public class test1 {
        public  static void main(String[] args) {
            TreeNode node1,node2,node3,node4,node5,node6,node7;
            BinaryTree binaryTree;

            TreeMap map;
            node7 = new TreeNode(7,null,null);
            node6 = new TreeNode(2,null,null);
            node5 = new TreeNode(0,null,null);
            node4 = new TreeNode(2,null,node7);
            node3 = new TreeNode(3,null,node6);
            node2 = new TreeNode(0,node5,node4);
            node1 = new TreeNode(4,node2,node3);
            //创建二叉树
            binaryTree = new BinaryTree(node1);
            System.out.print("该二叉树是否为空:");
            System.out.println(binaryTree.isEmpty());
            System.out.println(binaryTree.size());
            System.out.println(binaryTree.getHeight());
            System.out.print("该二叉树是否存在7:");
            System.out.println(binaryTree.contains(7));
            binaryTree.preorder();
            binaryTree.postorder();
            System.out.println("根节点的右子树:");
            System.out.println( binaryTree.getRight(node1));
        }
    }

(4)测试截图:

 

 

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

(1)二叉树依据先序序列和中序序列实现代码:(树的代码和上面一样)

public class creattree {
//先序与中序
    private int in = 0;
    private int pre = 0;
    public TreeNode buildTree(Object[] preorder, Object[] inorder) {
        return build(preorder, inorder, Integer.MIN_VALUE);
    }

    private TreeNode build(Object[] preorder, Object[] inorder, Object stop) {
        if (pre >= preorder.length) {return null;}
        if (inorder[in].equals(stop)) {
            in++;
            return null;
        }
        TreeNode node = new TreeNode(preorder[pre++]);
        node.setLeftChild(build(preorder, inorder, node.getValue()));
        node.setRightChild(build(preorder, inorder, stop));
        return node;
    }

    }

(2)测试代码:

import java.util.Scanner;

public class treetext2 {
    public static void main(String[] args) {
        System.out.println("请输入一个二叉树的前序序列");
        Scanner scan = new Scanner(System.in);
        String a = scan.nextLine();
        String[] a2 = a.split(" ");
        System.out.println("请输入一个二叉树的中序序列");
        String b = scan.nextLine();
        String[] b2 = b.split(" ");
        creattree ct = new creattree();
        System.out.println(ct.buildTree(a2,b2));
    }
}

(3)测试截图:

 

 

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

 

 

 

 

 

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

测试截图:

 

 (用栈存符号,list来放后缀)

码云链接:https://gitee.com/besti2023javads/hr20202304/commit/ca6df905dda8d0b434ca4cda93378b9c741d72bc

 

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

1.一开始创建树的时候将树建成了int型数据,后来改成了object,可以兼容一切类型。

2.使用递归时总是出错,没能很好的理解递归的要领。后来在算法上借鉴了csdn,完成了递归,完成了用两种已知的序列求树。

 

四、感悟:

麻了麻了,刚刚上手Android,刚想说安卓没我上次说的那么难,直接又来一波,树还好,到了后面用决策树,一开始直接上手做了一个贼简单的树,就和书上的差不多。后来来了兴趣,上网看看别人的,结果一看才知道,决策树要有决策能力和广泛性,人家的决策树都是基于算法制作出来的,想做好直接老老实实地去学习机器学习,计算熵,人都麻了,咋这么多东西啊,估计等我秃了我就能成为一名强大的程序员了。23333。

 

## 参考资料

-  《Java程序设计与数据结构教程(第二版)》
-  《机器学习(Tom.Mitchell著)》