2018-2019-20172329 《Java软件结构与数据结构》第七周学习总结

2018-2019-20172329 《Java软件结构与数据结构》第七周学习总结

教材学习内容总结

《Java软件结构与数据结构》第十一章-二叉查找树

一、概述

  • 1、什么是二叉查找树:二叉查找树是一种带有附加属性的二叉树,即对树中的每个结点,其左孩子都要小于其父结点,而父结点又小于或等于其右孩子。
  • 2、二叉查找树的定义是二叉树定义的扩展。
  • 3、操作:
操作 描述
addElement 往树中添加一个元素
removeElement 从书中删除一个元素素
removeAllOccurrences 从树中删除所指定元素的任何存在
removeMin 删除树中的最小元素
removeMax 删除树中的最大元素
findMin 返回一个指向树中最小元素的引用
findMax 返回一个指向树中最大元素的引用

二、用链表实现二叉查找树

  • 1、addElement操作

    • 过程:如果这个树为空,则新元素就将成为根结点。如果树非空,这个新元素会与树根元素进行对比。

      • (1)如果它小于根结点中存储的那个元素且根的左孩子为null,则这个新元素就将成为根的左孩子。
      • (2)如果这个新元素小于根结点中储存的那个元素且根的左孩子不是null,则会遍历根的左孩子,并再次进行比较操作。
      • (3)如果这个新元素大于或等于树根存储的那个元素且根的右孩子为null,则这个新元素会成为根的右孩子,并再次进行比较操作。
    • 图解:
  • 2、removeElement操作
    • 过程:

      • (1)如果被删除结点没有孩子,则replacement返回null。
      • (2)如果被删除结点只有一个结点,则replacement返回这个孩子。
      • (3)如果被删除结点有两个孩子,则replacement会返回中序后继者(因为相等元素会放到右边)
      • 注:从二叉查找树中删除一个元素时,必须推选出另一个结点来代替要被删除的那个结点。
    • 图解:
  • 3、 removeMin操作
    • 过程:

      • (1)如果树根没有左孩子,则树根就是最小元素,而树根的右孩子会变成新的根结点。
      • (2)如果树的最左边结点是一片叶子,则这片叶子就是最小元素,这时只需设置其父结点的左孩子引用为null即可。
      • (3)如果树的最左侧结点是一个内部结点,则需要设置其父结点的左孩子引用指向这个将删除结点的右孩子。
      • 注:二叉查找树的最右侧结点会存放最大元素,而其最左侧结点会存放最小元素。
    • 图解:

三、用有序列表实现二叉查找树

  • 1、BinarySearchTreeList实现的分析
操作 LinkedList BinarySearchTreeList
removeFirst O(1) O(log n)
removeLast O(n) O(log n)
remove O(n) O(log n)*
first O(1) O(log n)
last O(n) O(log n)
contains O(n) O(log n)
isEmpty O(1) O(1)
size O(1) O(1)
add O(n) O(log n)*

注:*add操作和remove操作都可能导致树变的不平衡

四、平衡二叉树

  • 1、下图显示了得到的二叉树,这个结果二叉树看作是一颗蜕化树,看起来更像是一个链表,而事实上,它的效率比链表还低。
  • 2、如果没有平衡假设,最坏情况下addElement操作时间复杂性是O(n)而不是O(log n),因为存在这种可能,即树根是书中的最小元素,而将被插入的元素可能是树中的最大元素。
  • 3、如果二叉查找树不平衡,其效率可能比线性结构的还要低。
  • 4、右旋
    • 用途:因为树根左孩子的左子树中较长的路径而导致的不平衡。
    • 步骤:
      • (1)使树根的左孩子元素成为新的根元素。
      • (2)使原根元素成为这个新树根的右孩子元素。
      • (3)使原树根的左孩子的右孩子,成为原树根的新的左孩子。
    • 图解:
  • 5、左旋
    • 用途:由树根右孩子的右子树中较长的路径而导致的不平衡。
    • 步骤:
      • (1)使树根的右孩子元素成为新的根元素。
      • (2)使原根元素成为这个新树根的左孩子元素。
      • (3)使原树根右孩子结点的左孩子,成为原树根的新的右孩子。
    • 图解:
  • 6、左右旋
    • 用途:对于由于树根左孩子的右子树中较长的路径而导致的不平衡,我们必须先让树根左孩子的右孩子绕着树根的左孩子进行一次左旋,然后再让所得的树根左孩子绕着树根进行一次右旋。
    • 图解:
  • 7、右左旋
    • 用途:对于由树根右孩子的左子树中较长路径而导致的不平衡,我们必须先让树根右孩子的左孩子,绕着树根右孩子进行一次右旋,然后再让所得的树根右孩子绕着树根进行一次左旋。
    • 图解:
  • 8、综上所述,平衡化树的一般性办法,其中自树根而下的路径最大长度必须不超过log2 n,而且自树根而下的路径最小长度必须不小于(log2 n)-1。
    五、实现二叉查找树:AVL树
  • 1、什么是AVL树
    • 它是上述树的一种变体。对于树中的每个结点,我们都会跟踪起左右子树的高度。对于树中任何结点,如果其平衡因子(平衡因子指的是左右子树的高度差,即右子树的高度减去左子树的高度)大于1或小于-1,则以该结点为树根的子树需要重新平衡。
  • 2、AVL树的操作(右旋,左旋,左右旋,右左旋)
    • 右旋:

      • 用在:平衡因子<-1且孩子的平衡因子<=-1
    • 左旋:
      • 用在:平衡因子>1且孩子的平衡因子>=1
    • 左右旋:
      • 用在:平衡因子<-1且孩子的平衡因子>=1
    • 右左旋:
      • 用在:平衡因子>1且孩子的平衡因子<=-1
  • 删除结点的实例图:
  • AVL树的性质:
    (1)左子树和右子树的高度之差的绝对值不超过1
    (2)树中的每个左子树和右子树都是AVL树
    (3)每个节点都有一个平衡因子(balance factor--bf),任一节点的平衡因子是-1,0,1之一
    六、实现二叉查找树:红黑树
  • 1、什么是红黑树:红黑树是一种平衡二叉查找树,其中的每个结点存储一种颜色(黑色或者红色,通常用一个布尔值来实现,值false等价于红色)
  • 2、规则:
    • (1)根结点为黑色。
    • (2)红色结点所有孩子都为黑色。
    • (3)从树根到树叶的每条路径都包含同样数目的黑色结点。

教材学习中的问题和解决过程

  • 问题1:在书中225页中有一个类叫做超类,为什么叫做超类?
  • 问题1解决方案:
  • 从网上查询了以后得知:
    是父类。
    超类(SuperClass) :用java术语来讲,被继承的类称为超类(SuperClass),也有叫做父类,继承的类称为子类。
    比如:
    public class A{//定义类A
    }
    public class B extends A{//定义类B,继承类A
    }
    则,类A就是超类或父类,类B叫子类
  • 问题2:涉及红黑树的问题,对于我们大家都是一个难点,所以在教材问题中将红黑树具体来写一下:
  • 问题2解决方案:
    (1)首先,我们需要了解到红黑树代表的是什么:红黑树是一种平衡二叉查找树,其中的每个结点存储一种颜色(红色或黑色,通常用一个布尔值来实现,值false等价于红色)。控制结点颜色的规则如下:
  • 根结点为黑色。
  • 红色结点的所有孩子都为黑色。
  • 从树根到树叶的每条路径都包含同样数目的黑色结点。

(2)我们了解到在某种程度上,红黑树中的平衡限制没有AVL树那样的严格。但是,它们的序仍旧是log n。

(3)我们分析一下红黑树的时间复杂度:

  • 红黑树的时间复杂度为: O(lgn)
  • 下面通过“数学归纳法”对红黑树的时间复杂度进行证明。
  • 定理:一棵含有n个节点的红黑树的高度至多为2log(n+1).
  • 证明:
    "一棵含有n个节点的红黑树的高度至多为2log(n+1)" 的逆否命题是 "高度为h的红黑树,它的包含的内节点个数至少为 2h/2-1个"。

    我们只需要证明逆否命题,即可证明原命题为真;即只需证明 "高度为h的红黑树,它的包含的内节点个数至少为 2h/2-1个"。

    从某个节点x出发(不包括该节点)到达一个叶节点的任意一条路径上,黑色节点的个数称为该节点的黑高度(x‘s black height),记为bh(x)。关于bh(x)有两点需要说明:

  • 第1点:根据红黑树的"特性(5) ,即从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点"可知,从节点x出发到达的所有的叶节点具有相同数目的黑节点。这也就意味着,bh(x)的值是唯一的!
  • 第2点:根据红黑色的"特性(4),即如果一个节点是红色的,则它的子节点必须是黑色的"可知,从节点x出发达到叶节点"所经历的黑节点数目">= "所经历的红节点的数目"。假设x是根节点,则可以得出结论"bh(x) >= h/2"。进而,我们只需证明 "高度为h的红黑树,它的包含的黑节点个数至少为 2bh(x)-1个"即可。

    到这里,我们将需要证明的定理已经由
    "一棵含有n个节点的红黑树的高度至多为2log(n+1)"
    转变成只需要证明
    "高度为h的红黑树,它的包含的内节点个数至少为 2bh(x)-1个"

(4)红黑树中元素插入:
将一个节点插入到红黑树中,需要执行哪些步骤呢?首先,将红黑树当作一颗二叉查找树,将节点插入;然后,将节点着色为红色;最后,通过旋转和重新着色等方法来修正该树,使之重新成为一颗红黑树。详细描述如下:

1、第一步: 将红黑树当作一颗二叉查找树,将节点插入。
红黑树本身就是一颗二叉查找树,将节点插入后,该树仍然是一颗二叉查找树。也就意味着,树的键值仍然是有序的。此外,无论是左旋还是右旋,若旋转之前这棵树是二叉查找树,旋转之后它一定还是二叉查找树。这也就意味着,任何的旋转和重新着色操作,都不会改变它仍然是一颗二叉查找树的事实。
好吧?那接下来,我们就来想方设法的旋转以及重新着色,使这颗树重新成为红黑树!

2、第二步:将插入的节点着色为"红色"。
为什么着色成红色,而不是黑色呢?为什么呢?在回答之前,我们需要重新温习一下红黑树的特性:

(1) 每个节点或者是黑色,或者是红色。

(2) 根节点是黑色。

(3) 每个叶子节点是黑色。 [注意:这里叶子节点,是指为空的叶子节点!]

(4) 如果一个节点是红色的,则它的子节点必须是黑色的。

(5) 从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。
将插入的节点着色为红色,不会违背"特性(5)"!少违背一条特性,就意味着我们需要处理的情况越少。接下来,就要努力的让这棵树满足其它性质即可;满足了的话,它就又是一颗红黑树了。o(∩∩)o...哈哈

3、第三步: 通过一系列的旋转或着色等操作,使之重新成为一颗红黑树。
第二步中,将插入节点着色为"红色"之后,不会违背"特性(5)"。那它到底会违背哪些特性呢?
对于"性质(1)",显然不会违背了。因为我们已经将它涂成红色了。
对于"性质(2)",显然也不会违背。在第一步中,我们是将红黑树当作二叉查找树,然后执行的插入操作。而根据二叉查找数的特点,插入操作不会改变根节点。所以,根节点仍然是黑色。
对于"性质(3)",显然不会违背了。这里的叶子节点是指的空叶子节点,插入非空节点并不会对它们造成影响。
对于"性质(4)",是有可能违背的!
那接下来,想办法使之"满足特性(4)",就可以将树重新构造成红黑树了。

(5)红黑树中元素删除:
-(1)重新平衡化(及重新着色):删除元素之后进行这一操作,是一种迭代过程,从删除点开始,一直上溯到树根。因此,如前所述,实现红黑树时最好在各个结点中包含一个父结点引用。这一过程的终止条件是(current==root)或(current.color==red),其中current是我们正在处理的这个结点。

  • (2)在删除中而言,焦点要放在当前结点的兄弟的颜色上。

    • 如果兄弟的颜色是red,则在做其他事之前必须完成如此处理步骤:

      • (1)设置兄弟的颜色为black;
      • (2)设置current的父亲的颜色为red;
      • (3)让兄弟绕着current的父亲向右旋转;
      • (4)设置兄弟等于current的父亲的左孩子;
    • 如果兄弟的两个孩子都是black或null,则需要做到:
      • (1)设置兄弟的颜色为red;
      • (2)设置current等于current的父亲;
    • 如果兄弟的两个孩子不全为black,则将查看兄弟的左孩子是否是black。如果是,则在继续之前必须完成如下步骤:
      • (1)设置兄弟的右孩子的颜色为black;
      • (2)设置兄弟的颜色为red;
      • (3)让兄弟的右孩子绕着兄弟本身向右旋转。
      • (4)设置兄弟等于current的父亲的左孩子;
    • 最后是兄弟的两个孩子都不为black这一情况,这时必须:
      • (1)设置兄弟的颜色为current的父亲的颜色;
      • (2)设置current的父亲的颜色为black;
      • (3)设置兄弟的左孩子的颜色为black;
      • (4)让兄弟绕着current的父亲向右旋转;
      • (5)设置current等于树根。
    • 该循环终止之后,我们要删除该结点,并设置其父亲的孩子引用为null。

代码调试中的问题和解决过程

  • 问题1:在补全代码的时候,发现有一个字段自己好像没有见过instanceof
  • 问题1解决方案:
    (1)自己也查了查这个到底是什么?用法如下:
  • 1、java 中的instanceof 是一个二元操作符(运算符)运算符,由于是字母组成,所以是Java的保留关键字,但是和>=,<=,==属同一类,它的作用是用来判断,instanceof 左边对象是否为instanceof 右边类的实例,返回一个boolean类型值。还可以用来判断子父类的所属关系。
  • 2、用法:
    boolean result = object instanceof class
    参数:
    Result:布尔类型。
    Object:必选项。任意对象表达式。
    Class:必选项。任意已定义的对象类。
    说明:
    如果 object 是 class 的一个实例,则 instanceof 运算符返回 true。如果 object 不是指定类的一个实例,或者 object 是 null,则返回 false。

代码链接


上周考试错题总结

测试还没有结束

结对及互评

  • 本周结对学习情况

    • 20172316赵乾宸
  • 博客中值得学习的或问题:
    • 内容详略得当;
    • 代码调试环节比较详细;
  • 基于评分标准,我给本博客打分:5分。得分情况如下:
  1. 正确使用Markdown语法(加1分):
  2. 模板中的要素齐全(加1分)
  3. 教材学习中的问题和解决过程, 一个问题加1分
  4. 代码调试中的问题和解决过程, 一个问题加1分
    • 20172316唐才铭
  • 博客中值得学习的或问题:

    • 内容详略得当;
    • 代码调试环节比较详细;
  • 基于评分标准,我给本博客打分:9分。得分情况如下:
  1. 正确使用Markdown语法(加1分):
  2. 模板中的要素齐全(加1分)
  3. 教材学习中的问题和解决过程, 一个问题加1分
  4. 代码调试中的问题和解决过程, 一个问题加1分

感悟

这一周很显然的感觉到自己时间很不够用,可能自己对于时间的分配还是有些不合理,总是做了些浪费时间的事情,也发现自己现在的时间观念没有过去那样很强了,希望自己可以经常反省,自己为什么会做事越来越慢。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积)
目标 5000行 30篇 400小时
第一周 0/0 1/1 6/6
第二周 1313/1313 1/2 20/26
第三周 901/2214 1/3 20/46
第四周 3635/5849 2/4 20/66
第五周 1525/7374 1/5 20/86
第六周 1542/8869 2/5 25/111
第七周 1391/10260 1/6 20/131

参考资料

蓝墨云班课
Java程序设计
红黑树之原理和算法实现
java中instanceof的用法和实战
AVL树(平衡二叉树)
AVL树算法思想和代码实现
AVL树的旋转图解和简单实现

原文地址:https://www.cnblogs.com/qh45wangwenbin/p/9893609.html

时间: 2024-11-09 22:07:18

2018-2019-20172329 《Java软件结构与数据结构》第七周学习总结的相关文章

20172305 2018-2019-1 《Java软件结构与数据结构》第一周学习总结

20172305 2018-2019-1 <Java软件结构与数据结构>第一周学习总结 教材学习内容总结 本周内容主要为书第一章和第二章的内容: 第一章 软件质量: 正确性(软件达到特定需求的程度) 可靠性(软件发生故障的频率和危害程度) 健壮性(很好处理错误情况的情况) 可用性(用户在软件中掌握和运行任务的容易程度) 可维护性(软件进行修改的容易程度) 可重用性(软件组件可被其他软件系统开发使用的容易程度) 可移植性(软件组成可用于多种计算机环境中的容易程度) 运行效率(不浪费资源的情况下软

2018-2019-20172321 《Java软件结构与数据结构》第九周学习总结

2018-2019-20172321 <Java软件结构与数据结构>第九周学习总结 教材学习内容总结 第15章 图 无向图 图由顶点和边组成. 顶点由名字或标号来表示,如:A.B.C.D: 边由连接的顶点对来表示,如:(A,B),(C,D),表示两顶点之间有一条边. 无向图:与树类似,图也由结点和这些结点之间的连接构成.这些结点是顶点,而结点之间的链接是边.无向图是一种边为无序结点对的图.于是,记做(A,B)的边就意味着A与B之间有一条从两个方向都可以游历的连接.边记作(A,B)和记作(B,A

201871010104-陈园园 《面向对象程序设计(java)》第六——七周学习总结

201871010104-陈园园 <面向对象程序设计(java)>第六——七周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业要求在哪里 https://www.cnblogs.com/lily-2018/p/11441372.html 作业学习目标 (1) 理解继承的定义: (2) 掌握子类的定义要求 (3) 掌握多态性的概念及用法: (4) 掌握抽象类的定义及用途. 第一部分:总结理论知识 1.类.超类和子类: a

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

20172306 2018-2019 <Java程序设计与数据结构(下)>第一周学习总结 教材学习内容总结 第一章 概述 (程序=数据结构+算法 软件=程序+软件工程) 1.1 软件质量 软件工程师一门关于高质量软件开发的技术和理论的学科 软件工程的目标:1.解决正确性问题 2.按时且在预算之内给出解决方案 3.给出高质量的解决方案 4.以合情合理的方式完成上面的事情 高质量软件的特征 正确性:我认为是我们所做的都是为了解决一个正确性问题. 可靠性:降低软件的故障程度和概率 健壮性:可以很好地

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

20172306<Java程序设计>第九周学习总结 教材学习内容总结 第十一章: try-catch语句.其中还有finally语句.try是进行某些操作,catch是捕获异常,并通过某些异常来进行某些操作.finally是无论是否有异常都会进行的语句.可以没有catch语句. 异常的传递.我觉得传递,主要是某地方的异常是由其他的方法引起的,异常就会传递到那个方法上.书中的例子可以很好的表现出来. IO异常.书中的内容主要是围绕异常来写.老师在蓝墨云中有写有关IO更为详细的内容.例如创建文件,

20172302 《Java软件结构与数据结构》第四周学习总结

2018年学习总结博客总目录:第一周 第二周 第三周 第四周 教材学习内容总结 第六章 列表 1.列表是对象的有序集合,在 List 界面中定义. List 接口表示集合框架中的列表.列表可以具有重复的元素.并且我们可以在列表中存储多个空值. 2.列表集合 是一种概念性的表示方法,其思想是使事物以线性列表的方式进行组织,就像栈和队列一样,列表也可以使用数组和链表来实现.列表集合没有内在的容量大小,它可以随着需要而增大.列表集合更一般化,可以在列表的中间和末端添加和删除元素. 3.列表可以分为有序

20172308《Java软件结构与数据结构》第四周学习总结

教材学习内容总结 第 6 章 列表 一. 列表集合 列表集合:一种概念性表示法,思想是使事物以线性列表的方式进行组织 特点: 列表集合没有内在的容量大小,它可以随着需要而增大 列表集合更具一般化,可以在列表的中间和末端添加和删除元素 列表也可以使用链表或数组实现 类型: 有序列表:元素按照元素的某种内在特性进行排序 无序列表:元素间不具有内在顺序,元素按照它们在列表中的位置排序 索引列表:其元素可以用数字索引来引用(顺序由使用者决定) 二. Java API没有任何类能直接实现以上描述的有序列表

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

一.学习内容 1.String类 2.StringTokenizer类 3.Scanner类——8.3知识 4.StringBuffer类——8.4知识 5.Date与Calendar类——8.5知识 (1) Date类 (2)Calendar类 6.日期的格式化——8.6知识 8.6.1 format方法 8.6.2 不同区域的星期格式 7.Math类.BigInteger类和Random类——8.7知识 8.7.1 Math类 8.7.3 Random类 8.数字格式化——8.8知识 8.8

20172302 《Java软件结构与数据结构》实验二:树实验报告

课程:<Java软件结构与数据结构> 班级: 1723 姓名: 侯泽洋 学号:20172302 实验教师:王志强老师 实验日期:2018年11月5日 必修/选修: 必修 实验内容 (1)参考教材p212,完成链树LinkedBinaryTree的实现(getRight,contains,toString,preorder,postorder:用JUnit或自己编写驱动类对自己实现的LinkedBinaryTree进行测试,提交测试代码运行截图,要全屏,包含自己的学号信息 (2)基于Linked

20172304 2018-2019《java软件结构与数据结构》 第一章 第二章学习总结

20172304 2018-2019<java软件结构与数据结构> 第一章 第二章学习总结 教材学习内容总结 第一章 概述 1.1软件质量: 高质量软件的几个特征: 正确性:软件在多大程度上满足其特定需求 可靠性:软件故障发生频率和危险程度 健壮性:出错情况下可以得到恰当处理的程度 可用性:用户学习和执行任务的难易程度 可维护性:对软件进行修改的难易程度 可重用性:软件组件可重用于其他软件系统开发的难易程度 可移植性:软件组件可以在多个计算机环境下使用的难易程度 运行效率:在不浪费资源的情况下