北京电子科技学院(BESTI)

实 验 报 告

课程:程序设计与数据结构
班级: 1623
姓名: 石亚鑫
学号:20162303

成绩: 2分
指导教师:娄嘉鹏 王志强
实验日期:10月23日

实验密级: 非密级
预习程度: 已预习
实验时间:15:25-17:15

必修/选修: 必修
实验序号: cs_03

实验内容

  1. 完成链树LinkedBinaryTree的实现(getRight,contains,toString,preorder,postorder)
    用JUnit或自己编写驱动类对自己实现的LinkedBinaryTree进行测试,提交测试代码运行截图

  2. 基于LinkedBinaryTree,实现基于(中序,先序)序列构造唯一一棵二㕚树的功能,比如教材P372,给出HDIBEMJNAFCKGL和ABDHIEJMNCFGKL,构造出附图中的树
    用JUnit或自己编写驱动类对自己实现的功能进行测试,提交测试代码运行截图

  3. 完成PP16.6
    提交测试代码运行截图,要全屏,包含自己的学号信息
    课下把代码推送到代码托管平台

  4. 完成PP16.8
    提交测试代码运行截图,要全屏,包含自己的学号信息
    课下把代码推送到代码托管平台

  5. 完成PP17.1
    提交测试代码运行截图,要全屏,包含自己的学号信息
    课下把代码推送到代码托管平台

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

实验步骤

(1) 实验一

public String toString() {String result = "";ArrayIterator <T> iter = new ArrayIterator <T> ();root.postorder ( iter );return result+iter;}public Iterator<T> preorder() {ArrayIterator <T> iter = new ArrayIterator <T> ();if (root != null)root.preorder ( iter );return  iter;}public Iterator<T> postorder() {ArrayIterator <T> iter = new ArrayIterator <T> ();if (root != null)root.postorder ( iter );return  iter;}

前序和后序与中序比较相似,调换一下顺序就可以了,toString本来应该按照层序遍历打印,但是层序遍历我暂时无法实现,于是就先打印后序。

(2) 实验二

(3) 实验三

public class TwentyQuestions {private LinkedBinaryTree<String> tree;public TwentyQuestions(){String e1 = "你觉得自己能够吃苦吗?";String e2 = "你觉得自己有耐心吗?";String e3 = "你有远大的目标吗?";String e4 = "你喜欢钻研吗?";String e5 = "希望你用你的耐心专注于一件事情并最终完成。";String e6 = "你觉得你的目标容易实现吗?";String e7 = "你有短期目标吗?";String e8 = "如果你拥有这些,那么好好坚持,吃得苦中苦,方为人上人。";String e9 = "实现目标刻苦钻研是必选的,加油!";String e10 = "一个好的目标是需要尽自己的努力来实现的,如果目标能轻而易举的实现,那绝对不是一个好的目标。";String e11 = "既然目标不是那么容易实现,那么你更应该努力实现,而不是自暴自弃。";String e12 = "你拥有短期目标却不肯吃苦实现它,那么你的短期目标只是空话。";String e13 = "你有梦想吗?";String e14 = "有梦想是好事,但是绝不能空想,要为实现目标付出努力。";String e15 = "你愿意做出一些改变吗?";String e16 = "那么从现在开始改变,确立一个小目标并努力实现,一步一个脚印,加油!";String e17 = "你觉得一个人的一生一定要做成某一件事情吗?";String e18 = "既然你心中依然有着想法,那么希望你能为此改变,不管什么时候,只要想改就不会晚。";String e19 = "有的时候平平淡淡也算一种生活方式,只要回首往事时能够对得起自己的内心就可以了。";LinkedBinaryTree<String> n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14,n15,n16,n17,n18,n19;n18 = new LinkedBinaryTree<String>(e18);n19 = new LinkedBinaryTree<String>(e19);n17 = new LinkedBinaryTree<String>(e17, n18, n19);n16 = new LinkedBinaryTree<String>(e16);n15 = new LinkedBinaryTree<String>(e15, n16, n17);n14 = new LinkedBinaryTree<String>(e14);n13 = new LinkedBinaryTree<String>(e13, n14, n15);n12 = new LinkedBinaryTree<String>(e12);n7 = new LinkedBinaryTree<String>(e7, n12, n13);n8 = new LinkedBinaryTree<String>(e8);n9 = new LinkedBinaryTree<String>(e9);n4 = new LinkedBinaryTree<String>(e4, n8, n9);n10 = new LinkedBinaryTree<String>(e10);n11 = new LinkedBinaryTree<String>(e11);n6 = new LinkedBinaryTree<String>(e6, n10, n11);n5 = new LinkedBinaryTree<String>(e5);n2 = new LinkedBinaryTree<String>(e2, n4, n5);n3 = new LinkedBinaryTree<String>(e3, n6, n7);tree = new LinkedBinaryTree<String>(e1, n2, n3);}public void diagnose(){Scanner scan = new Scanner(System.in);BinaryTree<String> current = tree;System.out.println ("你要根据现实情况做出选择:");while (current.size() > 1){System.out.println (current.getRootElement());if (scan.nextLine().equalsIgnoreCase("Y"))current = current.getLeft();elsecurrent = current.getRight();}System.out.println (current.getRootElement());}
}

跟原本代码比较相似,改一下字符串和树的构造顺序就可以了
实现如下:

(4) 实验四

(5) 实验五

在查找数上实现findMin和findMax方法,最小值就从根一直到最左,最大值就是从根一直到最右。

    public T findMin() {BTNode<T> node = null;if (root != null){node = node.getLeft();}return (T) node;}public T findMax() {BTNode<T> node = null;if (root != null){node = node.getRight();}return (T) node;}

(6) 实验六

参考链接1
参考链接2
参考链接3

HashMap继承自AbstractMap,实现了Map接口。
Map接口定义了所有Map子类必须实现的方法。Map接口中还定义了一个内部接口Entry(为什么要弄成内部接口?改天还要学习学习)。Entry将在后面有详细的介绍。
AbstractMap也实现了Map接口,并且提供了两个实现Entry的内部类:SimpleEntry和SimpleImmutableEntry。
定义了接口,接口中又有内部接口,然后有搞了个抽象类实现接口,抽象类里面又搞了两个内部类实现接口的内部接口

/*** 默认的初始容量,必须是2的幂。*/static final int DEFAULT_INITIAL_CAPACITY = 16;/*** 最大容量(必须是2的幂且小于2的30次方,传入容量过大将被这个值替换)*/static final int MAXIMUM_CAPACITY = 1 << 30;/*** 默认装载因子,这个后面会做解释*/static final float DEFAULT_LOAD_FACTOR = 0.75f;/*** 存储数据的Entry数组,长度是2的幂。看到数组的内容了,接着看数组中存的内容就明白为什么博文开头先复习数据结构了*/transient Entry[] table;/*** map中保存的键值对的数量*/transient int size;/*** 需要调整大小的极限值(容量*装载因子)*/int threshold;/***装载因子*/final float loadFactor;/*** map结构被改变的次数*/transient volatile int modCount;接着是HashMap的构造方法。/***使用默认的容量及装载因子构造一个空的HashMap*/public HashMap() {this.loadFactor = DEFAULT_LOAD_FACTOR;threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);//计算下次需要调整大小的极限值table = new Entry[DEFAULT_INITIAL_CAPACITY];//根据默认容量(16)初始化tableinit();}
/*** 根据给定的初始容量的装载因子创建一个空的HashMap* 初始容量小于0或装载因子小于等于0将报异常 */public HashMap(int initialCapacity, float loadFactor) {if (initialCapacity < 0)throw new IllegalArgumentException("Illegal initial capacity: " +initialCapacity);if (initialCapacity > MAXIMUM_CAPACITY)//调整最大容量initialCapacity = MAXIMUM_CAPACITY;if (loadFactor <= 0 || Float.isNaN(loadFactor))throw new IllegalArgumentException("Illegal load factor: " +loadFactor);int capacity = 1;//设置capacity为大于initialCapacity且是2的幂的最小值while (capacity < initialCapacity)capacity <<= 1;this.loadFactor = loadFactor;threshold = (int)(capacity * loadFactor);table = new Entry[capacity];init();}
/***根据指定容量创建一个空的HashMap*/public HashMap(int initialCapacity) {this(initialCapacity, DEFAULT_LOAD_FACTOR);//调用上面的构造方法,容量为指定的容量,装载因子是默认值}
/***通过传入的map创建一个HashMap,容量为默认容量(16)和(map.zise()/DEFAULT_LOAD_FACTORY)+1的较大者,装载因子为默认值*/public HashMap(Map<? extends K, ? extends V> m) {this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);putAllForCreate(m);}

TreeMap有Values、EntrySet、KeySet、PrivateEntryIterator、EntryIterator、ValueIterator、KeyIterator、DescendingKeyIterator、NavigableSubMap、AscendingSubMap、DescendingSubMap、SubMap、Entry共十三个内部类。
Values
// 从类的定义可以看出,Values是一个集合类

class Values extends AbstractCollection<V> {// 提供集合类Values的迭代器public Iterator<V> iterator() {return new ValueIterator(getFirstEntry());}// 返回TreeMap中保存的节点数public int size() {return TreeMap.this.size();}// 判断TreeMap中是否存在Value为o的节点public boolean contains(Object o) {return TreeMap.this.containsValue(o);}// 删除一个对象public boolean remove(Object o) {// 遍历TreeMapfor (Entry<K,V> e = getFirstEntry(); e != null; e = successor(e)) {// 寻找值相等的节点if (valEquals(e.getValue(), o)) {// 删除找到的节点deleteEntry(e);return true;}}return false;}// 清空TreeMappublic void clear() {TreeMap.this.clear();}
}

Values类实际上是一个代理,多数方法都是调用TreeMap的方法。在Values的iterator()方法中返回了一个ValuesIterator对象,下面来看和迭代器相关的内部类。PrivateEntryIterator是TreeMap中和迭代器相关的类的基础,以下是PrivateEntryIterator的内容。

abstract class PrivateEntryIterator<T> implements Iterator<T> {// 指向next的引用
Entry<K,V> next;
// 保留对上一次返回节点的引用Entry<K,V> lastReturned;int expectedModCount;// 构造方法,lastReturned置空,next指向传入的节点PrivateEntryIterator(Entry<K,V> first) {expectedModCount = modCount;lastReturned = null;next = first;}// 判断是否还有下一个节点public final boolean hasNext() {return next != null;}// 返回下一个节点final Entry<K,V> nextEntry() {Entry<K,V> e = next;if (e == null)throw new NoSuchElementException();if (modCount != expectedModCount)throw new ConcurrentModificationException();// next移动到它的继承者next = successor(e);// 记录被返回的节点lastReturned = e;// 返回原先记录的next节点return e;}// 前一个节点final Entry<K,V> prevEntry() {Entry<K,V> e = next;if (e == null)throw new NoSuchElementException();if (modCount != expectedModCount)throw new ConcurrentModificationException();// 获取指定节点的“前任”(按遍历次序的前一个节点)next = predecessor(e);// 记录被返回的节点lastReturned = e;return e;}// 移除最近一次被返回的节点public void remove() {if (lastReturned == null)throw new IllegalStateException();if (modCount != expectedModCount)throw new ConcurrentModificationException();// deleted entries are replaced by their successorsif (lastReturned.left != null && lastReturned.right != null)/* 如果被删除节点有两个孩子,删除节点e的时候e的引用会被修改为指向原节点的继承者,所以这里先保留next对lastReturned的引用,这样在删除节点后就能获取到继承者的引用,继而继续遍历树 */next = lastReturned;// 删除节点deleteEntry(lastReturned);expectedModCount = modCount;lastReturned = null;}
}

PrivateEntryIterator类的prevEntry()方法用到了predecessor(Entry<K,V> t)方法,下面对这个方法进行介绍。

 predecessor(Entry<K,V> t)方法返回传入节点的“前一个”节点,至于前一个节点是哪个节点,这和树的遍历次序相关。根据successor(Entry<K,V> t)和predecessor(Entry<K,V> t)方法可以推出TreeMap中树的遍历次序是中根遍历(左孩子-根-右孩子)。
static <K,V> Entry<K,V> predecessor(Entry<K,V> t) {if (t == null)return null;
else if (t.left != null) {// 获得左孩子Entry<K,V> p = t.left;// 对左孩子进行遍历,获取左孩子最右的子孙while (p.right != null)p = p.right;return p;
} else {// 获取t的父节点Entry<K,V> p = t.parent;Entry<K,V> ch = t;
// 沿着右孩子向上查找继承者,直到根节点或找到节点ch是其父节点的右孩子的节点while (p != null && ch == p.left) {ch = p;p = p.parent;}return p;}
}

统计自己的PSP(Personal Software Process)时间

步骤 耗时 百分比
需求分析 60min 13.6%
代码实现 300min 68.1%
测试 60min 13.6%
分析总结 20min 4.5%

转载于:https://www.cnblogs.com/syx390234975/p/7751202.html

20162303 实验二 树相关推荐

  1. 数据结构实验二 树和二叉树的实现

    广州大学学生实验报告 开课实验室:计算机科学与工程实验(电子楼418A)     2019年5月13日 学院 计算机科学与教育软件学院 年级.专业.班 计算机科学与技术172班 姓名 学号 17061 ...

  2. 2017-2018-1 20162316刘诚昊 实验二 树

    20162316刘诚昊 2017-2018-2 <Java程序设计>第二次实验 树 实验链接: 实验二 树-1-实现二叉树 实验二 树-2-中序先序序列构造二叉树 实验二 树-3-决策树 ...

  3. 数据结构-实验二  树和二叉树的实现

     广州大学学生实验报告 开课实验室:计算机科学与工程实验(电子楼417)     2018年05月16日 学院 计算机科学与教育软件学院 年级.专业.班 网络161 姓名 卟咚君 学号 1606100 ...

  4. 20172319 实验二《树》实验报告

    20172319 2018.11.04-11.12 实验二<树> 实验报告 课程名称:<程序设计与数据结构> 学生班级:1723班 学生姓名:唐才铭 学生学号:20172319 ...

  5. 数据结构_C语言_实验二_树 ——还原二叉树

    文章目录 实验二 树 1. 实验目的 2. 实验内容 3. 实验要求 4. 实验过程 (1) 问题描述 (2) 数据结构与算法设计 (3) 程序实现 (4) 实验结果 (5) 实验总结 实验二 树 - ...

  6. 20172310《程序设计与数据结构》(下)实验二:二叉树实验报告

    20172310<程序设计与数据结构>(下)实验二:二叉树实验报告 报告封面 课程:<软件结构与数据结构> 班级: 1723 姓名: 仇夏 学号:20172310 实验教师:王 ...

  7. java 二叉树实验报告_20172310《程序设计与数据结构》(下)实验二:二叉树实验报告...

    20172310<程序设计与数据结构>(下)实验二:二叉树实验报告 报告封面 课程:<软件结构与数据结构> 班级: 1723 姓名: 仇夏 学号:20172310 实验教师:王 ...

  8. 20172328《程序设计与数据结构》实验二:树

    20172328<程序设计与数据结构>实验二:树 课程:<软件结构与数据结构> 班级: 1723 姓名: 李馨雨 学号:20172328 实验教师:王志强老师 实验日期:201 ...

  9. 实验二 二叉树的操作与实现

    前言 记录实验,同时也是记录常见数据结构算法的实现. 广州大学学生实验报告 开课实验室:计算机科学与工程实验(电子楼416A) 学院 计算机科学与网络工程学院 实验课程 数据结构实验 实验项目 实验二 ...

最新文章

  1. 顺丰职级分成4级_14368!4月全国程序员均薪新鲜出炉!
  2. SPOJ MULTQ3 7299 Multiples of 3 (区间更新)
  3. 【蓝桥杯】子串分值---笔记
  4. linux qt绘框,Qt绘制异形窗体
  5. Qt学习(四):qt读写文件
  6. 【LeetCode】191. Number of 1 Bits
  7. angular 字符串转换成数字_Python | 一文看懂Python列表、元组和字符串操作
  8. 基于 Kubernetes 的微服务部署即代码
  9. go mod管理golang包
  10. 随想录(平台软件和项目代码)
  11. oracle11g手工监听配置,手工在同一主机创建主备库oracle11g active dataguard
  12. 微信开发者工具安装教程
  13. 在eclipse中安装WindowsBuilder插件
  14. mi5splus android9,小米MIUI 9.5国际版稳定版开始推送:超30款机型将获更新
  15. 模块一 day09 文件操作相关
  16. 维和医疗分队患者信息管理系统的开发与研究
  17. python猜大小程序_「每日一练」巧用python实现猜大小的游戏
  18. CAD二次开发之选择集过滤
  19. 两名一流高校硕士同年毕业论文高度雷同惹争议,怎么过的查重?
  20. 大数据架构选型与设计

热门文章

  1. 信号回勾产生的原因_为什么照片放大会有噪点?产生噪点的4个因素,来了解一下...
  2. java lang runtimeexception什么意思_Java基础之异常
  3. acivity 横屏_Activity横竖屏切换时先看到横屏/竖屏再变换回竖屏/横屏
  4. 在linux看数据库表空间,Linux平台达梦数据库V7之表空间管理
  5. 计算机操作基本知识公务员,公务员计算机类操作系统知识.pdf
  6. 一个mysql可以存多少数据类型_mysql一张表到底能存多少数据?
  7. pytorch WHAT IS TORCH.NN REALLY?
  8. Scala paralle
  9. opencv 直方图均等化
  10. php邀请码演示代码,WordPress主题纯代码实现邀请码功能