20172320 2018-2019-1 《Java程序设计》第六周学习总结
教材学习内容总结
- 树是一种非线性结构,其元素被组织成了一个层次结构
- 树由一个包含结点和边的集构成,其中的元素被存储在这些结点中,边则将一个节点和另一个结点连接起来,树的根就是位于该树顶层的唯一结点
- 位于树中较低层的结点是上一层结点的孩子,一个结点只有一个双亲,但是一个结点可以有多个孩子,同一双亲的两个结点称为兄弟
- 根结点是树中唯一一个没有双亲的结点,没有任何孩子的结点称为叶子,一个至少有一个孩子的非根结点称为一个内部结点
- 通过计算从根到该结点所必须越过的边数目,就可以确定其路径长度
- 树分类的最重要的一条标准是树中任一结点可以具有的最大孩子数目,这个值也称为度。对结点所含有的孩子数目无限制的树称为广义树,每一结点限制为不超过n个孩子的树称为一颗n元树,结点最多具有两个孩子的树称为二叉树
- 树的所有叶子都位于同一层或者至少是彼此相差不超过一个层,就称之为是平衡的,含有m个元素的平衡n元树具有的高度为lognm,一颗含有n个结点的平衡二叉树的高度为log2n
- 某树是平衡的,且底层所有叶子都位于树的左边,则认为该树是完全的;一颗n元树的所有叶子都位于同一层且每一个结点要么是一片叶子要么正好具有n孩子,则称此树是满的
- 从维护树的结构和阶的角度看,树具有其他结构中不存在的相关成本,当n相对较小时,相对于树所涉及的成本,树实现和线性结构之间并不存在特别显著的差别,随着n的增加,树的效率会更好
- 树的遍历:前序遍历:从根结点开始,访问每一结点及其孩子
伪代码
···
Visit node
Traverse(left child)
Traverse(right child)
中序遍历:从根结点开始,访问结点的左孩子,然后是该结点,再然后是任何剩余节点
伪代码
Traverse(left child)
Visit node
Traverse(right child)
后序遍历:从根结点开始,访问结点的孩子,然后是该结点
Traverse(left child)
Traverse(right child)
Visit node
层序遍历:从根节点开始,访问每一层的所有结点,一次一层
- 二叉树的操作
| 操作 | 说明 |
| -------- | :---------------:|
| getRoot | 返回指向二叉树跟的引用 |
| isEmpty | 判定该树是否为空 |
| size | 判定树中的元素数目 |
| contains | 判定指定目标是否在该树中 |
|find|如果找到指定元素,则返回指向其的引用 |
|toString|返回树的字符串表示|
|iteratorInOrder|为树的中序遍历返回一个迭代器|
|iteratorPreOrder|为树的前序遍历返回一个迭代器|
|iteratorPostPrder|为树的后序遍历返回一个迭代器|
|iteratorLevelOrder|为树的层序遍历返回一个迭代器|
不存在往树中添加元素的操作,因为在指定该二叉树的用途和结构之前,我们无法知道如何或更具体地说往该树的如何添加一个元素,同时任何从树中删除一个或多个元素的操作,可能会与该树的用途或结构发生冲突
- 二叉树的性质
性质1 在二叉树的第i层最多有2i-1个结点
性质2 深度为k的二叉树最多有2k-1个结点
性质3 对任何一颗二叉树,如果其叶结点个数为n0,度为2的结点数为n2,则有n0=n2+1
- 完全二叉树的性质
性质1 具有n个结点的完全二叉树的高度为:log2n取下整数后+1
性质2 如果将一个有n个结点的完全二叉树自顶向下,同一层自左向右连续给结点编号1,2,...,n,则对于任意结点i(1<=i<=n),有: 若i=1,则该i结点是树根,它无双亲;
若2i>n,则编号为i的节点无左孩子,否则它的左孩子是编号为2*i的结点;
若2i+1>n,则编号为i的结点无右孩子,否则右孩子的编号为2*i+1
# 教材中遇到的问题和解决过程
- 问题1:祖先的定义?除了根还会有其他结点被称为祖先吗?
- 解决方案:定义:从根节点到某一节点一路顺下来的除了该节点的所有节点都是该节点的祖先节点
根节点是同一棵树中除本身外所有结点的祖先,是树中所有结点的最终祖先,
## 代码调试中的问题和解决过程
- 问题1:pp9.3如何计算程序执行时间
- 解决方案:找到两种,`currentTimeMillis`和`nanoTime`,分别以毫秒和纳秒为单位计算,伪代码如下
long startTime=System.currentTimeMillis(); //获取开始时间
doSomeThing(); //测试的代码段
long endTime=System.currentTimeMillis(); //获取结束时间
System.out.println("程序运行时间: "+(end-start)+"ms");
//伪代码
long startTime=System.currentTimeMillis(); //获取开始时间
doSomeThing(); //测试的代码段
long endTime=System.currentTimeMillis(); //获取结束时间
System.out.println("程序运行时间: "+(end-start)+"ms");
long startTime=System.nanoTime(); //获取开始时间
doSomeThing(); //测试的代码段
long endTime=System.nanoTime(); //获取结束时间
System.out.println("程序运行时间: "+(end-start)+"ns");
//伪代码
long startTime=System.nanoTime(); //获取开始时间
doSomeThing(); //测试的代码段
long endTime=System.nanoTime(); //获取结束时间
System.out.println("程序运行时间: "+(end-start)+"ns");
```
错题分析
- ________ traversal means visit the left child, then the right child, then the node.
A .preorder
B .postorder
C .inorder
D .level-order
分析:B
后序遍历表示访问左子节点,然后访问右子节点,最后访问节点 - ___________ traversal means visit the nodes at each level, one level at at time, starting with the root.
A .preorder
B .postorder
C .inorder
D .level-order
分析:D
层序遍历意味着访问每个级别的节点,每次访问一个级别,从根节点开始。 - Inorder traversal means visit the left child, then the node, then the right child.
A .True
B .False
分析:A
中序遍历意味着访问左子节点,然后访问节点,最后访问右子节点。 Level-order traversal means visit the nodes at each level, one level at at time, starting with the root.
A .True
B .False
分析:B
层序顺序遍历意味着访问每个级别的节点,每次访问一个级别,从根节点开始结对及互评
点评过的同学博客和代码
- 本周结对学习情况
20172327 - 结对学习内容
•阅读第10章节,运行教材上的代码
•完成程序设计项目PP10.1、PP10.3、PP10.5
•完成课后自测题,并参考答案学习
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 0/0 | 1/2 | 20/20 | |
第二周 | 328/328 | 1/3 | 20/40 | |
第三周 | 1597/ 1925 | 1/4 | 20/60 | |
第四周 | 1153/3850 | 1/5 | 20/80 | |
第五周 | 1583/5433 | 1/6 | 20/100 | |
第六周 | 1515/6948 | 1/7 | 20/120 |