2017-2018-1 20162305 实验二 树

2017-2018-1 20162305 实验二 树

一、链树的实现

1、实验要求

  • 参考教材p375,完成链树LinkedBinaryTree的实现(getRight,contains,toString,preorder,postorder)
    用JUnit或自己编写驱动类对自己实现的LinkedBinaryTree进行测试,提交测试代码运行截图,要全屏,包含自己的学号信息

2、实验过程和思路

  • 这个实验是利用链表结构实现链表二叉树,教材中已经给出了LinkedBinaryTree类和BTNode类,LinkedBinaryTree中的preorder和postorder两个方法的实现要在BTNode类的完善的基础上实现。下面一一说明LinkedBinaryTree其他方法的实现。
  • getRight方法:该方法是返回右结点值,实现方法同getLeft方法相同

public LinkedBinaryTree<T> getRight() {
        if (root == null)
            System.out.print("Find operation failed. \" + \"No such element in tree.");
        LinkedBinaryTree<T> result = new LinkedBinaryTree <T>();
        result.root = root.getRight();

        return result;
     }

  • contain方法:该方法判断树中是否包含有该元素。实现这个方法,我利用的是这个类中已经给出的find方法,判断该元素是否存在,如果find找到了该元素则返回true,不包含则返回else。
public boolean contains (T target) {

        if (root.find(target) == null)
            return false;
        else
            return true;

    }

  • isEmpty方法:判断树是否为空,如果root为空返回true,不为空则返回false。
public boolean isEmpty() {
        if (root == null)
            return true;
        else
            return false;
     }

  • toString方法:使用super继承的toString方法实现

 public String toString() {
        return super.toString();
    }

  • preorder方法:该方法实现树的前序遍历,前序遍历,先访问根,再由左至右地遍历整棵树。先将元素element赋给iter,再判断左右两结点是否为空,不为空,left或right结点用preorder方法处理iter,这一方法的实现在BTNode结点类中,

 public ArrayIterator preorder(ArrayIterator<T> iter) {
        iter.add(element);
        if (left != null)
            left.preorder(iter);
        if (right != null)
            right.preorder(iter);

        return null;
    }

  • postorder方法:该方法实现树的后序遍历,后序遍历,自左至右遍历整个树,然后访问根。实现这个方法只需要先判断左右结点,再添加元素即可。

public void postorder(ArrayIterator <T> iter) {
        if (left != null)
            left.postorder(iter);
        if (right != null)
            right.postorder(iter);
        iter.add(element);
    }

3、实验成果截图

(实验一截图)

二、构造二叉树

1、实验要求

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

2、实验过程和思路

  • 重建二叉树方法:这个方法是这次实验中的核心代码,这个方法的实现我并没有很好地独立完成,这个方法是参照着网上查阅的相关资料实现的。重构二叉树,定义了pre和in两个数组,已经两个数组开头与结尾的四个元素,在方法中先定义一个节点tree,定义tree结点的左右都为空。判断当先序数组的首尾元素和中序数组的首尾元素都相等时候,直接返回tree这个结点。利用root和for循环找到中序数组中与先序数组中preStart所指向的元素的相等的元素,得到root值。利用root值和inStart和inEnd确定左长度和右长度,根据左右长度,分别给左右结点赋值,最后返回tree。
public static BTNode reConstructBinaryTreeCore(int[] pre, int[] in, int preStart, int preEnd, int inStart, int inEnd) {
        BTNode tree = new BTNode(pre[preStart]);
        tree.left = null;
        tree.right = null;
        if (preStart == preEnd && inStart == inEnd) {
            return tree;
        }
        int root = 0;
        for(root= inStart; root < inEnd; root++){
            if (pre[preStart] == in[root]) {
                break;
            }
        }
        int leftLength = root - inStart;
        int rightLength = inEnd - root;
        if (leftLength > 0) {
            tree.left = reConstructBinaryTreeCore(pre, in, preStart+1, preStart+leftLength, inStart, root-1);
        }
        if (rightLength > 0) {
            tree.right = reConstructBinaryTreeCore(pre, in, preStart+1+leftLength, preEnd, root+1, inEnd);
        }
        return tree;
    }

  • 构建二叉树:根据先序数组和中序数组,,利用重构二叉树方法构建新的唯一二叉树。

public static BTNode BuildBinaryTree(int[] pre,int[] in){
        if(pre == null || in == null){
            return null;
        }
        BTNode node = reConstructBinaryTreeCore(pre, in, 0, pre.length-1, 0, in.length-1);
        return node;
    }

3、实验成果截图

(实验二截图)

三、决策树

1、实验要求

  • 完成PP16.6:在称为20问的游戏中,一个人先想好一个物体,另一个人通过yes-or-no问题尝试判定这个物体是什么。目标是用尽可能少的问题判定出物体。设计并实现程序,利用决策树来玩20问游戏,基于一组预设的可能的物体。
    提交测试代码运行截图,要全屏,包含自己的学号信息

2、实验过程和思路

  • 本次实验的思路和方法同教材上程序16.5 BackPainExpert实现方法和思路相同,首先构造一个树,设计好相关的问题,再利用LinkedBinaryTree实现问答过程,根据答案返回相关的结果,最后得出结论。我设计的是一个猜手机的问题。

3、实验成果截图

实验四、表达式树

1、实验要求

  • 完成PP16.8:设计并实现程序,使用二叉树来表示表达式树。提供方法对树进行计算,得到表达式的结果。
    提交测试代码运行截图,要全屏,包含自己的学号信息

2、实验方法和思路

  • 这个实验是将中缀表达式利用树转换为后缀表达式,再对后缀表达式进行计算。这其中最重要的部分就是利用树将中缀表达式转化为后缀表达式。我是这么做的,在createTree方法中,先定义两个数组列表,分别存放运算符和数字。首先分辨出数字和运算符,分别存放在两个数组中,把最后的数组加到结点中。然后取出两个数字和一个操作符,重复直到操作符取完为止。最后让根节点等于最后一个结点。返回root,构造完成。后缀表达式的计算,我利用的是上学期学过的四则运算类完成。先将树利用toString类型转换,再利用计算类计算,在测试类中得到结果。

3、实验成果截图

(实验四截图)

五、二叉查找树

1、实验要求

  • 完成PP17.1
    提交测试代码运行截图,要全屏,包含自己的学号信息

2、实验方法和思路

  • 教材中的二叉查找树中需要补全findMax方法和findMin方法。根据二叉查找树的相关性质可知,根的左边元素恒小于根,右边元素恒大于根,想找到最小或者最大的元素,只需要找到最左侧和最右侧的元素即可。

  • findMax


public T findMax() {
        BTNode<T> node =  root;
        while (node.getRight() != null)
            node = node.getRight();
        return  node.getElement();
    }

  • findMin

 public T findMin() {
        BTNode<T> node =  root;
        while (node.getLeft() != null)
            node = node.getLeft();
        return  node.getElement();
    }

3、异常处理

  • 我的二叉查找树的add方法存在问题,只能添加进去一个元素,后来在张旭升同学的帮助下,通过单步跟踪一点一点找到了问题的根源并得到解决。只能添加一个元素,因为之前写好的类中在原有结点的基础上又定义了两个空的左右结点,导致添加了第一个元素后直接结束。删除了两个空节点并再对相关方法进行调整,这个问题得到了解决。感谢张旭升同学对我的帮助,通过这次问题的解决我也学到了如何更好地利用单步跟踪解决问题。

4、实验成果截图

(实验五截图)

六、红黑树分析

实验要求

  • 参考http://www.cnblogs.com/rocedu/p/7483915.html对Java中的红黑树(TreeMap,HashMap)进行源码分析,并在实验报告中体现分析结果

实验过程

  • TreeMap:这个代码也是实现了一个树的结构。这个代码写的逻辑清晰,思维缜密。所有的方法都环环相扣,该方法继承了AbstrTree类中的方法,其中的getEntry、firstEntry、lastEntry方法等等都和教材中的树的方法写的相似,采用了相同的思路。源码中提供了更加全面的方法,各个方法的逻辑和实现方法都值得我们学习。
  • HashMap:这个代码之中的一些方法实现,也和教材中代码有着相似之处,学习这些源码结合教材有助于提高我们对代码的理解。这些方法中有的简洁,有的采用了大量的循环判断,这些都值得去研究学习。
posted @ 2017-10-29 18:40  20162305李昱兴  阅读(346)  评论(0编辑  收藏  举报