20162307 2017-2018-1 《程序设计与数据结构》第7周学习总结
教材学习内容总结(第十六章 树)
概述
- 本章是在讲非线形集合-树
- 树的使用及实现,定义与树相关的术语,分析树的实现
16.1 树
- 树:非线性结构,其元素组成为一个层次结构
- 分类:主要分为线性和非线性
- 树由一组结点及一组边构成,结点用来保存元素,边表示结点之间的连接。
16.1.1 树的分类
- 树的度表示树中任意结点的最大子结点数
- 有m个元素的平衡n叉树的高度是logm(n为底)
- 两种特殊的二叉树:满二叉树和完全二叉树
16.2 树的遍历
-
4种树的遍历的基本方法:先序遍历、中序遍历、后序遍历、层序遍历
-
已知前序、中序遍历,求后序遍历
例:
前序遍历: GDAFEMHZ
中序遍历: ADEFGHMZ
画树求法:
第一步,根据前序遍历的特点,我们知道根结点为G
第二步,观察中序遍历ADEFGHMZ。其中root节点G左侧的ADEF必然是root的左子树,G右侧的HMZ必然是root的右子树。
第三步,观察左子树ADEF,左子树的中的根节点必然是大树的root的leftchild。在前序遍历中,大树的root的leftchild位于root之后,所以左子树的根节点为D。
第四步,同样的道理,root的右子树节点HMZ中的根节点也可以通过前序遍历求得。在前序遍历中,一定是先把root和root的所有左子树节点遍历完之后才会遍历右子树,并且遍历的左子树的第一个节点就是左子树的根节点。同理,遍历的右子树的第一个节点就是右子树的根节点。
第五步,观察发现,上面的过程是递归的。先找到当前树的根节点,然后划分为左子树,右子树,然后进入左子树重复上面的过程,然后进入右子树重复上面的过程。最后就可以还原一棵树了。该步递归的过程可以简洁表达如下:
1. 确定根,确定左子树,确定右子树。
2. 在左子树中递归。
3. 在右子树中递归。
4. 打印当前根。
那么,我们可以画出这个二叉树的形状:
前序遍历:
public void preOrderTraverse1(TreeNode root) {
if (root != null) {
System.out.print(root.val+" ");
preOrderTraverse1(root.left);
preOrderTraverse1(root.right);
}
}
16.3 树的实现策略
- 使用数组实现二叉树时,位于位置n的元素的左孩子在(2n-1)的位置,其右孩子在(2*(n+1))的位置
- 树的基于数组的存储链实现方式可以占据数组中的连续位置,不管树是不是完全树
教材学习中的问题和解决过程
关于16.2程序中的ArrayIterator
- 仔细地看书,发现书中有一段文字:
所以我自己尝试写了一下ArrayIterator
import java.util.ArrayList;
import java.util.Iterator;
import java.util.function.Consumer;
/**
* Created by zhangyunqi on 2017/10/22.
*/
public class ArrayIterator<T> implements Iterator<T> {
private LinearNode <T> iter;
private ArrayList list;
public ArrayIterator ()
{
iter=null;
list=null;
}
public void add(Object obj) {
this.list.add ( obj );
}
public String toString() {
String result = "";
LinearNode<T> current = iter;
while (current != null) {
result = result + (current.getElement ()).toString () + "
";
current = current.getNext ();
}
return result;
}
public Iterator<T> iterator() {
return null;
}
public void forEach(Consumer<? super T> action) {
}
@Override
public boolean hasNext() {
return false;
}
@Override
public T next() {
return null;
}
@Override
public void remove() {
}
public void forEachRemaining(Consumer <? super T> action) {
}
}
public interface Iterator {
public void add();
public void inorder();
public void preorder();
public void postorder();
}
代码调试中的问题和解决过程
问题一
在调试代码中,发现ArrayIterator和Iterator的缺少,仿照ArrayStack和 Stack写。解决办法在上边
代码托管
上周考试错题总结
结对及互评
本周结对学习情况
- [20162303](http://www.cnblogs.com/syx390234975/)
- 结对学习内容
- 学习第十六章
- 研究上课时讲的ppt
其他(感悟、思考等,可选)
这周学习状态比上周好,我会继续努力的
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 68/68 | 1/1 | 12/12 | |
第三周 | 298/366 | 2/3 | 18/30 | |
第五周 | 688/1162 | 2/5 | 20/50 | |
第七周 | 1419/2581 | 4/9 | 20/70 |
尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
耗时估计的公式
:Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。
-
计划学习时间:20小时
-
实际学习时间:20小时
(有空多看看现代软件工程 课件
软件工程师能力自我评价表)