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:当前结点的双亲结点是红色,其叔叔结点为黑色,当前结点是其双亲结点的左孩子:
    • 删除
      • 有三种情况:

        • 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程序设计与数据结构》第七周学习总结的更多相关文章

  1. 20172328 2018—2019《Java软件结构与数据结构》第二周学习总结

    20172328 2018-2019<Java软件结构与数据结构>第二周学习总结 概述 Generalization 本周学习了第三章集合概述--栈和第四章链式结构--栈.主要讨论了集合以 ...

  2. 20172306 2018-2019-2 《Java程序设计与数据结构》第九周学习总结

    20172306 2018-2019-2 <Java程序设计与数据结构>第九周学习总结 教材学习内容总结 无向图 图是由结点和这些结点之间的连接构成 就图来说,结点叫做顶点,结点之间的连接 ...

  3. 20172306 2018-2019 《Java程序设计与数据结构》第一周学习总结

    20172306 2018-2019 <Java程序设计与数据结构(下)>第一周学习总结 教材学习内容总结 第一章 概述 (程序=数据结构+算法 软件=程序+软件工程) 1.1 软件质量 ...

  4. 20172306《Java程序设计与数据结构》第九周学习总结

    20172306<Java程序设计>第九周学习总结 教材学习内容总结 第十一章: try-catch语句.其中还有finally语句.try是进行某些操作,catch是捕获异常,并通过某些 ...

  5. 《JAVA程序设计》_第七周学习总结

    一.学习内容 1.String类--8,1知识 Java专门提供了用来处理字符序列的String类.String类在java.lang包中,由于java.lang包中的类被默认引入,因此程序可以直接使 ...

  6. 20172319 2018.04.11-16 《Java程序设计教程》 第6周学习总结

    20172319 2018.04.11-16 <Java程序设计教程>第6周学习总结 目录 教材学习内容总结 教材学习中的问题和解决过程 代码调试中的问题和解决过程 代码托管 上周考试错题 ...

  7. 20172319 《Java程序设计教程》第8周学习总结

    20172319 2018.04.24-05.03 <Java程序设计教程>第8周学习总结 目录 教材学习内容总结 教材学习中的问题和解决过程 代码调试中的问题和解决过程 代码托管 上周考 ...

  8. 20172319 《Java程序设计教程》第7周学习总结

    20172319 2018.04.11-16 <Java程序设计教程>第7周学习总结 目录 教材学习内容总结 教材学习中的问题和解决过程 代码调试中的问题和解决过程 代码托管 上周考试错题 ...

  9. 20172319 《Java程序设计教程》 第9周学习总结

    20172319 2018.05.06-05.14 <Java程序设计教程>第9周学习总结 目录 教材学习内容总结 教材学习中的问题和解决过程 代码调试中的问题和解决过程 代码托管 上周考 ...

  10. 20172319 《Java程序设计教程》 第10周学习总结

    20172319 2018.05.09-05.21 <Java程序设计教程>第10周学习总结 目录 教材学习内容总结 教材学习中的问题和解决过程 代码调试中的问题和解决过程 代码托管 上周 ...

随机推荐

  1. Oracle的SQL优化思路

    个人总结SQL脚本优化,大体如下: (1)选择最有效率的表名顺序(只在基于规则的优化器中有效): ORACLE解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表dir ...

  2. 大量Python开源第三方库资源分类整理,含菜鸟教程章节级别链接

    Python是一种面向对象的解释型计算机程序设计语言,由荷兰人Guido van Rossum于1989年发明.因其具有丰富和强大的库,它常被称为胶水语言,能够把用其它语言制作的各种模块(尤其是C/C ...

  3. Delphi ClientDataSet 主从结构 BUG

    使用ADO控件 .ClientDataSet .增加了从表与主表的关连字段 SheetID,别的设置全为默认.如图1所示 图1 ======= 问题 BUG: 打开主表与从表,先不对主表进行任何操作. ...

  4. python3 正则匹配[^abc]和(?!abc)的区别(把多个字符作为一个整体匹配排除)

    目的:把数字后面不为abc的字符串找出来 如1ab符合要求,2abc不符合要求 str = '1ab' out = re.match(r'\d+(?!abc)',str) str1 = '1abc' ...

  5. Crontab 执行时没有环境变量!

    Crontab 执行时没有环境变量! Crontab 执行时没有环境变量! Crontab 执行时没有环境变量! 重要的事情说三遍,浪费我半天时间去找问题!! 非系统默认工具,执行时候需要加全路径!!

  6. anaconda安装Opencv报错:Could NOT find PythonLibs: Found unsuitable version "2.7.6",

    机器上装了两个python,一个是默认的,一个是anaconda.安装opencv时就报错了: -- Found PythonInterp: /home/deeplp/anaconda2/bin/py ...

  7. C# 构造函数中base和this的使用。

    使用base时,首先给父类中的构造函数赋值. 使用this时,先调用父类无参构造函数,再调用自身其他构造函数并对其赋值,最后调用自身当前构造函数.

  8. CSS3奇特的渐变示例

    渐变 4个维度去理解渐变 线性渐变 径向渐变 新写法 老写法 最后的老写法镜像渐变可能不太准确.其余都完全正确 <!DOCTYPE html> <html> <head& ...

  9. celery(一) application

    Application application celery在使用之前,必须首先实例化.e.g. app = Celery() app 是线程安全的,即:不同配置.组件和任务的多个app可以共存在同一 ...

  10. 2018.5.12 storm数据源kafka堆积

    问题现象: storm代码依赖4个源数据topic,2018.5.12上午8点左右开始收到告警短信,源头的4个topic数据严重堆积. 排查: 1.查看stormUI, storm拓扑结构如下: 看现 ...