20172322 《程序设计与数据结构》第六周学习总结
教材学习内容总结
本章的内容主要讲树,顾名思义树与队列、栈、列表最大的区别就在于,树是一种非线性结构,其元素是一种层次结构存放。
树:
-
用于描述树相关的术语有非常多,除了之前常用的结点(node)还有边(edge)、孩子、兄弟等等,其中我认为比较重要的有:
- 内部节点:非根节点,且至少有一个子结点
- 同胞节点:属于同一节点的子结点
- 叶节点:不包含任何子节点的结点
-
树的分类:可以有非常多的分类方式,但是最重要的标准是任一结点可以具有的最大孩子数目,成为度(order),n元树的定义也是由此定义的
-
树的数组实现:因为数组实现树比较麻烦,所以在树的数组实现中书上同样模拟了链接策略,如图所示。
-
树的遍历,
-
前序遍历:从根节点开始访问每一个节点及其孩子。如图:
-
中序遍历:从根节点开始(注意并不是先访问根节点),中序遍历根节点的左子树,然后是访问根节点,最后中序遍历根节点的右子树。如图:
-
后序遍历:从左到右先叶子后节点的方式遍历访问左右子树,最后访问根节点。如图:
-
层序遍历:从树的第一层,也就是根节点开始访问,从上到下逐层遍历,在同一层中,按从左到右的顺序结点逐个访问。如图:
-
二叉树
(二叉树极其重要,以至于用三级标题来写它,而不是一般的一个点。)二叉树又名二元树,它的每一个结点最多具有两个孩子结点。
- 首先我们来看看百度百科的对树的定义:二叉树是一个连通的无环图,并且每一个顶点的度不大于3。有根二叉树还要满足根结点的度不大于2。有了根结点之后,每个顶点定义了唯一的父结点,和最多2个子结点。然而,没有足够的信息来区分左结点和右结点。如果不考虑连通性,允许图中有多个连通分量,这样的结构叫做森林。
- 与之前类似,本次教材也给出了二叉树的ADT
BinaryTreeADT
其中的基本方法有:getRoot
、isEmpty
、size
、contains
、find
、toString
和一些迭代器相关的方法。 - 书上提供了两种二叉树的例子:表达式树和决策树。
- 关于二叉树的一些性质,例如,
- 在二叉树的第i层最多有2i-1个节点
- 深度为k的二叉树最多有2k-1个节点
- 对于任何一个二叉树,如果其叶结点个数为n0,度为2的结点数尾n2,则有:n0=n2+1
- 关于完全二叉树的一些性质,例如,
- 具有n个结点的完全二叉树的高度为:log2n取下整数后+1
- 如果将一个有n个结点的完全二叉树自顶向下,同一层自左向右连续给结点编号1,2,...,n,则对于任意结点i(1<=i<=n),有:
- 若i=1,则该i结点是树根,它无双亲;
- 若2i>n,则编号为i的节点无左孩子,否则它的左孩子是编号为2*i的结点;
- 若2i+1>n,则编号为i的结点无右孩子,否则右孩子的编号为2*i+1
教材学习中的问题和解决过程
- 问题一:对于树的遍历问题,看了书以后感觉不太明白,前序遍历、中序遍历、后序遍历、层序遍历这四个遍历在书上的解释不太清晰,看题以后也不太明白。
- 问题一解决方案:在网上查询了相关的内容,得到了相应的解答。《二叉树的四种遍历方法笔记》。让我豁然开朗。
暂时没有遇到其他的问题。
代码调试中的问题和解决过程
- 问题一:在编写PP10.5要求补全二叉树的
contains
方法时,第一次自己的代码如下
public boolean contains(T targetElement) {
BinaryTreeNode current = root;
BinaryTreeNode temp = root;
boolean contains = false;
if (current == null) {
contains = false;
}
if (current.getElement().equals(targetElement)) {
contains = true;
}
while (current.right != null)
{
if (current.right.getElement().equals(targetElement)) {
contains = true;
} else {
current = current.right;
}
}
while (temp.left != null)
{
if (temp.left.getElement().equals(targetElement))
{
contains = true;
}
else {
temp = temp.left;
}
}
return contains;
}
这导致我测试该方法时只要是在判断非根节点就会出现程序一直运行无法停止的情况。
- 问题一解决方案:仔细回顾了自己的代码,发现问题应该出现在while循环中,发现虽然我在代码中写到了如果查找/未找到到该元素就返回true/false然后返回该循环,没有跳出操作,导致程序一直运行。所以说我分别改为了
if(current.right.getElement().equals(taretElement)) {
contains = true;
break;
}
和
if (temp.left.getElement().equals(targetElement))
{
contains = true;
break;
}
后便解决了该问题。
代码托管“点这里跳转到码云”
上周考试错题总结
上周没有测试,所以没有错题
结对及互评
- 博客中值得学习的或问题:
- 范雯琪同学的博客课本上的学习内容总结部分写得十分详细,应该向她学习
- 代码中值得学习的或问题:
- commit提交的解释清晰明了,我觉得我应该学习。
点评过的同学博客和代码
- 本周结对学习情况
-
结对学习内容
- 我们一起实现了本周需要实现的一些PP项目并且给互相讲述了其中的基本原理。
其他
- 感悟:在之前学习的基础上树的实现已经变得简单,只是迭代器和递归问题有些遗忘。
课本单词
(本部分用于收集本章节后的生词)
- tree:树
- node:节点
- edge:边
- root:根节点 最高层的节点
- level:层
- child:子节点
- sibling:同胞节点
- leaf:叶节点
- internal node:内部结点
- path:路径
- ancestor:祖先节点 位于当前节点以上的节点
- descendant:后代节点
- path length:路径长度
- tree height:树高度
- tree order:树的阶
- general tree:一般树 对子节点无限制的树
- n-ary tree:n元树
- binary tree:二叉树
- balanced:平衡 如果所有叶节点都位于同一层,或至少位于其他某一层,就认为是平衡树
- complete:完全
- full:完整
- freelist
- binary search tree:二叉查找树
- preorder traversal:前序遍历
- inorder traversal:中序遍历
- postorder traversal:后序遍历
- level-order traversal:层序遍历
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 0/5000 | 2/2 | 8/8 | 认真学习!积极向上 |
第二周 | 812/812 | 1/3 | 22/30 | |
第三周 | 814/1626 | 1/4 | 20/50 | |
第四周 | 1386/3012 | 2/6 | 20/70 | 愉快的国庆节就要结束了... |
第五周 | 1222/3234 | 1/7 | 30/100 | |
第六周 | 1327/4561 | 2/7 | 30/100 | 啦啦啦啦啦 |
-
计划学习时间:30小时
-
实际学习时间:30小时
-
改进情况:规范commit行为。