20172306 2018-2019-2 《Java程序设计与数据结构》第七周学习总结
20172306 2018-2019-2 《Java程序设计与数据结构》第七周学习总结
教材学习内容总结
概述
- 二叉查找树是一种含有附加属性的二叉树,即其左孩子小于父结点,而父结点又小于或等于右孩子。
- 二叉查找树的定义是二叉树定义的扩展。
- 二叉查找树的各种操作:addElement ,removeElement ,removeAllOccurrences(从树中删除所指定元素的任何存在) ,removeMin ,removeMax ,findMin ,finMax
用链表实现二叉查找树
每个BinaryTreeNode对象要维护一个指向结点所存储元素的引用,另外还要维护指向结点的每个孩子的引用。
addElement操作(假设:根结点为node)
- (1)如果树为空,则插入的element为根结点
- (2)如果树不为空,element<node,且node的左孩子为null,则null的空为element;如果node的左孩子不为null,则继续遍历根的左孩子,再进行操作。
- (3)如果树不为空,element>= node,且node的右孩子为null,则null的空为element;如果node的右孩子不为null,则继续遍历根的右孩子,再进行操作。
removeElement操作
- 与前面的线性结构研究不同,这里不能简单地通过删除指定结点的相关引用指针而删除该结点。相反,这里必须推选出另一个结点来代替要被删除的那个结点。受保护方法replacement返回指向一个结点的引用,该结点将代替要删除的结点 。
- 替换的replacement的代码如下:
private BinaryTreeNode<T> replacement(BinaryTreeNode<T> node) {
BinaryTreeNode<T> result = null;
if ((node.left == null) && (node.right == null)) {
result = null;
} else if ((node.left != null) && (node.right == null)) {
result = node.left;
} else if ((node.left == null) && (node.right != null)) {
result = node.right;
} else {
BinaryTreeNode<T> current = node.right;// 初始化右侧第一个结点
BinaryTreeNode<T> parent = node;
// 获取右边子树的最左边的结点
while (current.left != null) {
parent = current;
current = current.left;
}
current.left = node.left;
// 如果当前待查询的结点
if (node.right != current) {
parent.left = current.right;// 整体的树结构移动就可以了
current.right = node.right;
}
result = current;
}
return result;
}
选择替换结点的三种情况:
- 如果被删除结点没有孩子,则replacement返回null
- 如果被删除结点只有一个孩子,则replacement返回这个孩子
- 如果被删除结点有两个孩子,则replacement会返回中序后继者(因为相等元素会放到右边)
对于这个删除,有几种情况:
- (1)要删除的结点无孩子结点;删除方法:直接删除该结点
- (2)要删除的结点只有左孩子结点;删除方法:删除该结点且使被删除节点的双亲结点指向被删除节点的左孩子结点;
- (3)要删除的结点只有右孩子结点;删除方法:删除该结点且使被删除节点的双亲结点指向被删除结点的右孩子结点
- (4)要删除的结点有左、右孩子结点;删除方法:找中序后继者,用它的值填补到被删除节点中,再来处理该结点的删除

removeAllOccurrences操作
- 我觉得这个操作主要还是利用removeElement。和removeElement不同的是,我们会利用一个find的操作来判断有没有这个targetElement的存在,有的话,就继续利用removeElement的相关方法进行删除。没有这个targetElement就抛出异常。
public void removeAllOccurrences(T targetElement) {
removeElement(targetElement);//在我看来就是利用了之前的删除元素的方法
try {
while (contains((T) targetElement))
removeElement(targetElement);
}
catch (Exception ElementNotFoundException) {
}
}
removeMin操作(二叉查找树的最右侧结点会存放最大元素,最左侧结点会存放最小元素)
- 我认为removeMax和removeMin的原理是相同的,懂了removeMin就会removeMax了。
- 最小元素的位置的3种情形:(假设:树根是root)
- (1)如果root没有左孩子,则root为min,root的右孩子就会变成新的root
- (2)如果树的最左侧结点是一片叶子,则这个叶子就是min,这时只需设置其父结点的左孩子引用为null
- (3)如果树的最左侧结点是一个内部结点,则需要设置其父结点的左孩子引用指向这个将删除结点的右孩子

用有序列表实现二叉查找树
- 树的主要使用之一就是尾其他集合提供高效的实现
- add和remove操作都会对树的平衡有影响,而这一点同时对所使用的算法的分析也有影响

平衡二叉查找树
如果二叉查找树不平衡其效率可能比线性结构的还要低
右旋:a.根的左孩子为新的根元素;b.原根成为新根的右孩子;c.原根的左孩子的右孩子为原根的新的左孩子。(如果是因为树根左孩子的左子树中较长的路径而导致的不平衡,右旋可以解决它)

左旋:a.根的右孩子为新的根元素;b.原根成为新根的左孩子;c.原根的右孩子的左孩子为原根的新的右孩子。 (对于由树根右孩子的右子树中较长路径而导致的不平衡,左旋可以解决它)

右左旋:先将子树中左旋变成右子树比较长的,然后右旋。
左右旋:先将子树中右旋变成左子树比较长的,然后左旋。
了解了左旋和右旋,其实右左旋和左右旋都是在这两个的基础上进行的。

这两种二叉查找树:我们以上的这几种操作都是在平衡二叉查找树的条件下进行的,而AVL树和红黑树就是将不是平衡的树变成平衡树。
树只有两个途径能变得不平衡:插入结点和删除结点。
- 原因:我认为是根据之前的插入和删除的操作,可以知道在插入和删除的时候,会对树的长度发生很大的变化,所以极可能导致不平衡。
对于AVL树和红黑树,都要从插入和删除结点的位置需要上溯树,所以通常最好实现为每个结点都包含一个指向其父结点的引用。
实现二叉查找树:AVL树
- 平衡化树的一般性方法:其中自树根而下的路径最大长度必须不超过logn,而且自树根而下的路径最小长度必须不小于logn-1。
- 平衡因子:其左右子树的高度差(即右子树的高度减去左子树的高度)——大于1或者小于-1,则以该结点为树根的子树需要重新平衡。
- 我认为对于AVL的右旋、左旋、右左旋、左右旋的过程和之前的没有区别,我们学习AVL树的就是,它注明了平衡因子,而这个就是为了我们在看到一个树时,判断是利用哪种旋的方式的。
实现二叉查找树:红黑树
- 红黑树的样子:

- 其中白色代表红色,黑色代表黑色。
- 结点存储一种颜色(红色或黑色,通常用一个布尔值来实现,false等价于红色)
- 规则
- (1)根结点为黑;
- (2)叶子的结点也为黑,因为每个叶子后面的都跟着一个null,null是黑色结点,所以是黑色结点。
- (3)红结点的所有孩子都为黑色;
- (4)从树根到树叶的每条路径都包含同样数目的黑色结点
- 由于红色结点不能有红色孩子,所以路径中至多有一半结点是红色结点、至少有一半结点是黑色结点
- 红黑树的样子:
对于红黑树的插入和删除,书中给的很模糊,老师讲过之后,其实我觉得还是老师的PPT更懂一些,因为有图,条理也很清晰。(附上几张PPT内容)
- 插入
- 一般设置要插入结点的颜色为Red。
- 插入时分为三种情况:
- 被插入为根结点,那么就直接染色为黑色
- 被插入结点的双亲结点为黑色,不用做,因为对于黑色没有什么影响。
- 被插入结点的双亲结点为红色,这就会有三种情况:
- case1:当前结点的双亲结点A为红色,且其祖父的另一个子结点为红:

- case2:当前结点的双亲结点A为红色,且其叔叔结点为黑色,且其为其双亲结点的右孩子:

- case3:当前结点的双亲结点是红色,其叔叔结点为黑色,当前结点是其双亲结点的左孩子:

- case1:当前结点的双亲结点A为红色,且其祖父的另一个子结点为红:
- 删除
- 有三种情况:
- one:要删除结点没有孩子结点:直接删除
- two:要删除结点只有一个孩子结点:直接使用其孩子结点代替要删除结点
- three:要删除结点有左右孩子结点:要考虑后继结点的问题

- 有三种情况:
- 插入
教材学习中的问题和解决过程
- 问题1:在书中说,LinkedBinarySearchTree类提供了两个构造函数,这两个函数都只是引用了其超类(LinkedBinaryTree类),但是好像很少听到超类这个词
- 问题1解决方案:我上网查了下,就暴露了我以前书看的不好的问题了。原来超类就是父类啊。
public class A{//定义类A
}
public class B extends A{//定义类B,继承类A
}
则,类A就是超类或父类,类B叫子类
问题2:书中这句,如果被删除结点有两个孩子,则replacement会返回中序后继者,中序后继者这个词我没有理解?
问题2解决方案:这个位置我回到第十章那个中序遍历那看了一眼。用一个图来表示我的收获。

而且我还得到了,其实中序后继者,就是找这个要删除的结点的右子树中最小的那个值,这个值就是中序后继者。问题3:书中的红黑树部分说,规则之一是从树根到树叶的每条路径都包含同样数目的黑色结点,但是书中有个图

问题3解决方案:这个是不对的,因为不符合规则中的每条路径的黑色结点相同;且这个可以看出,对于红黑树,它的平衡性不是特别的严格。
代码调试中的问题和解决过程
问题1:在对LinkedBinarySearchTree进行测试时,出现了这样的问题。
,它出现了地址。问题1解决方案:最开始我觉得肯定没问题啊,后来出现这样了。这个问题其实挺普遍的,是toString方法没写的缘故,我忘记写了!!!它这个也是树,所以我直接就将第十章的printTree的给拿过来了。

代码托管

上周考试错题总结
- 上周没有错题
结对及互评
点评模板:
- 博客中值得学习的或问题:
- 内容总结的比较详细
- 问题有个分析,虽然很详细,但是吧,如果可以自己理解,我觉得会更好
点评过的同学博客和代码
- 本周结对学习情况
- 20172325
- 结对照片
- 结对学习内容
- 一起学习了第十一章的内容
- 一起进行了编程十一章的作业
其他(感悟、思考等,可选)
觉得吧,这一章的红黑树真的是迷的一批,我都看不懂,只能慢慢看,但是这一章的内容在第十章的基础上再看的话,我就觉得好像比刚接触树时更懂点了,而且我还在书中把一些转换的过程自己试了试,尽力的搞懂它,我觉得这也算是一种进步吧。
学习进度条
| 代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
|---|---|---|---|---|
| 目标 | 5000行 | 30篇 | 400小时 | |
| 第一周 | 0/0 | 1/1 | 6/6 | |
| 第二周 | 985/985 | 1/1 | 18/24 | |
| 第三周 | 663/1648 | 1/1 | 16/40 | |
| 第四周 | 1742 /3390 | 2/2 | 44/84 | |
| 第五周 | 933/4323 | 1/1 | 23/107 | |
| 第六周 | 1110/5433 | 2/2 | 44/151 | |
| 第七周 | 1536/6969 | 1/1 | 56/207 |
参考资料
20172306 2018-2019-2 《Java程序设计与数据结构》第七周学习总结的更多相关文章
- 20172328 2018—2019《Java软件结构与数据结构》第二周学习总结
20172328 2018-2019<Java软件结构与数据结构>第二周学习总结 概述 Generalization 本周学习了第三章集合概述--栈和第四章链式结构--栈.主要讨论了集合以 ...
- 20172306 2018-2019-2 《Java程序设计与数据结构》第九周学习总结
20172306 2018-2019-2 <Java程序设计与数据结构>第九周学习总结 教材学习内容总结 无向图 图是由结点和这些结点之间的连接构成 就图来说,结点叫做顶点,结点之间的连接 ...
- 20172306 2018-2019 《Java程序设计与数据结构》第一周学习总结
20172306 2018-2019 <Java程序设计与数据结构(下)>第一周学习总结 教材学习内容总结 第一章 概述 (程序=数据结构+算法 软件=程序+软件工程) 1.1 软件质量 ...
- 20172306《Java程序设计与数据结构》第九周学习总结
20172306<Java程序设计>第九周学习总结 教材学习内容总结 第十一章: try-catch语句.其中还有finally语句.try是进行某些操作,catch是捕获异常,并通过某些 ...
- 《JAVA程序设计》_第七周学习总结
一.学习内容 1.String类--8,1知识 Java专门提供了用来处理字符序列的String类.String类在java.lang包中,由于java.lang包中的类被默认引入,因此程序可以直接使 ...
- 20172319 2018.04.11-16 《Java程序设计教程》 第6周学习总结
20172319 2018.04.11-16 <Java程序设计教程>第6周学习总结 目录 教材学习内容总结 教材学习中的问题和解决过程 代码调试中的问题和解决过程 代码托管 上周考试错题 ...
- 20172319 《Java程序设计教程》第8周学习总结
20172319 2018.04.24-05.03 <Java程序设计教程>第8周学习总结 目录 教材学习内容总结 教材学习中的问题和解决过程 代码调试中的问题和解决过程 代码托管 上周考 ...
- 20172319 《Java程序设计教程》第7周学习总结
20172319 2018.04.11-16 <Java程序设计教程>第7周学习总结 目录 教材学习内容总结 教材学习中的问题和解决过程 代码调试中的问题和解决过程 代码托管 上周考试错题 ...
- 20172319 《Java程序设计教程》 第9周学习总结
20172319 2018.05.06-05.14 <Java程序设计教程>第9周学习总结 目录 教材学习内容总结 教材学习中的问题和解决过程 代码调试中的问题和解决过程 代码托管 上周考 ...
- 20172319 《Java程序设计教程》 第10周学习总结
20172319 2018.05.09-05.21 <Java程序设计教程>第10周学习总结 目录 教材学习内容总结 教材学习中的问题和解决过程 代码调试中的问题和解决过程 代码托管 上周 ...
随机推荐
- 利用checkbox自带属性indeterminate构建含部分选中状态的树状结构
本来上个月就像发的,但是一直忙啊忙的也没时间整理,所以拖到了现在. 好吧上面这句就是废话,我就是感概下.下面是正文. 前段时间在弄一个轻量级的web项目,要构建一个树状结构目录,同时希望能把部分选中的 ...
- python url监控 并邮件报警
import timeimport requestsimport smtplibfrom email.mime.text import MIMETextimport datetime def Send ...
- visual studio 2013 几个测试工具(Nunit 3、xUnit)
一.Nunit 3 1.在解决方案里添加一个类库——引用——右键(如下图)) 3.搜索nunit 并安装(如图) 3.注意引入命名空间并给测试类和测试方法添加特性(如图) 4.如果测试通过则为绿色(如 ...
- 服务器还原阿里云Mysql数据库
https://www.percona.com/doc/percona-xtrabackup/2.3/installation/yum_repo.html
- Django中manger/QuerySet类与mysql数据库的查询
Django中的单表操作 1.精确查询 #查询的结果返回是容器Query Set的函数(Query Set模型类)# 1. all() 查询的所有的符合条件的结果,支持正向索引,支持索引切片,不 ...
- redis数据转移随笔
生产环境有一批版本比较老的redis主从架构,是一主多从,版本是2.8 由于想迁移到阿里云上,那么问题来了,怎么把redis数据转移到阿里云上 为了省事,阿里云也是和生产环境一样的版本,架构也一致,其 ...
- Redis集群以及自动故障转移测试
在Redis中,与Sentinel(哨兵)实现的高可用相比,集群(cluster)更多的是强调数据的分片或者是节点的伸缩性,如果在集群的主节点上加入对应的从节点,集群还可以自动故障转移,因此相比Sen ...
- Django框架的探索
django框架的路由 django2 路由支持正则匹配,如: re_path(r'^category/(?P<category_id>\d+)/$',CourseCategoryView ...
- parallel Stream 学习
首先,我们需要了解下ForkJoinPool.ForkJoin框架是从jdk7中新特性,它同ThreadPoolExecutor一样,也实现了Executor和ExecutorService接口.它使 ...
- java operate
class OperateDemo { public static void main(String[] args) { /* + - * / %(取余数) */ int x = 2810; Syst ...