20172323 2018-2019-1 《程序设计与数据结构》第八周学习总结

20172323 2018-2019-1 《程序设计与数据结构》第八周学习总结

教材学习内容总结

本周学习了第12章优先队列与堆


  • 12.1 堆
  • 堆是具有两个附加属性的一棵二叉树,它是一棵完全树,对于每一结点,它小于或等于其左孩子和右孩子,这样定义下的堆是最小堆,如果对于每一结点,它大于或等于其左孩子和右孩子,那么它就是最大堆。
  • 最小堆将其最小元素存储在该二叉树的根处,且其根的两个孩子同样也是最小堆。
操作 说明
addElement 将给定元素添加到该堆中
removeMin 删除堆的最小元素
findMin 返回一个指向堆中最小元素的引用
  • 如图是一个最小堆
  • addElement方法将给定的Comparable元素添加到堆中的恰当位置处,且维持该堆的完全性属性和有序性属性

    如果一棵二叉树是平衡的,及所有叶子都位于h或者h-1层,其中h为log2n,n是树中的元素数目,以及所有h层中的叶子都位于该树的左边,那么该树就被认为是完全的。因为堆是一棵完全树,所以对于新插入的结点只存在一个正确的位置,要么是h层左边的下一个空位置,要么就是h+1层左边的第一个位置(如果h层是满的话)

  • 新结点添加之后,将考虑堆的排序性。,该结点将于它的双亲结点进行比较,如果新结点小则要与双亲结点进行互换,之后再沿树往上进行比较直至新值大于双亲或者位于根结点。
  • 在堆实现中,我们会对树中的最末一个结点(最末一片叶子)进行跟踪记录。

    2添加到堆之后,将于其双亲进行比较上浮直至堆满足其顺序属性
  • removeMin操作将删除最小堆中的最小元素并返回他,最小堆中的元素即是它的根结点,为了保持树的合法性,需要有一个能替换根的合法元素,且它是树中最末一片叶子上的元素。将最末一片叶子移至根处之后,又需要将该堆进行重新排序。排序方法需要将该结点与最小孩子进行比较然后逐渐下沉到合适的位置。借用上图,如果将根结点1删去,那么最末叶子6就将成为新的根结点,它将与2、5进行比较最终落在5现在的位置,而2将成为新的根结点。

  • 12.2 使用堆:优先级队列
  • 优先级队列就是遵循两个排序规则的集合。一是具有更高优先级的项目在先,二是具有相同优先级的项目使用先进先出方法确定其排序。
  • 虽然最小堆根本就不是一个队列,但是他却提供了一个高效的优先级队列实现

  • 12.3 用链表实现堆
  • 堆中结点必须存储指向其双亲的指针。
  • 链表实现addElement操作的时间复杂度为O(logn)
  • removeMin操作的时间复杂度同样为O(logn)。
  • findMin操作时间复杂度为O(1)

  • 12.4 用数组实现堆
  • 堆的数组实现比链表实现更为简洁。
  • 在二叉树的数组实现中,树的根位于位置0处,对于每一结点n,n的左孩子将位于数组的2n+1
    处,n的右孩子将位于数组的2(n+1)位置处
  • 数组实现不需要确定新结点双亲,时间复杂度与链表实现相同,但数组实现效率更高
  • 链表实现与数组实现的removeMin操作的复杂度同为O(logn)

  • 12.5 使用堆:堆排序
  • 堆排序的由两步构成:添加列表的每个元素,然后一次删除一个元素
  • 堆排序的复杂度为O(nlogn)

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

  • 问题1:链表实现堆的过程中的addElement操作第一步要确定要插入结点的双亲,为什么在最坏的情况下要从堆的右下结点遍历到根结点之后还要再从根结点遍历到堆的左下结点?
  • 问题1解决方案:这个问题我思考了小半个小时,添加的第一步需要确定插入结点的双亲,因为需要比较双亲结点的值与新结点的值,决定新结点是否要上浮。所以最坏的情况应该是新结点一直上浮到根结点,此时按最小堆的定义来看,添加元素这一操作应该是停止了,因为堆顶是最小元素了,它的左孩子和右孩子的值都应该比它要小,所以不需要继续遍历它的左孩子直到左下结点了吧。和同学讨论之后,才发现我的理解错在哪里了。它这里指的是遍历的最坏情况需要从右下结点一直到根再到左下结点,而不是结点互相之间的比较需要让结点上浮之后再次下沉(事实上跟我分析的一样,他也无法做到)。它这里指的是查找确定新结点的双亲结点的最坏情况

    如上丑图,添加元素时刚好遇见满树的情况,需要从右下最后一片叶子开始找起,一直到左下结点,才最终确定要插入的元素的双亲结点。

  • 问题2:对书上代码getNextParentAdd方法的理解
  • 问题2解决方案
        HeapNode<T> result = lastNode;
        while ((result != root) && (result.getParent().getLeft() != result))
            result = result.getParent();
        if (result != root)
            if (result.getParent().getRight() == null)
                result = result.getParent();
            else {
                result = (HeapNode<T>) result.getParent().getRight();
                while (result.getLeft() != null)
                    result = (HeapNode<T>) result.getLeft();
            }
        else
            while (result.getLeft() != null)
                result = (HeapNode<T>) result.getLeft();

        return result;

首先教材讲到,这是一个返回指向插入结点的双亲结点的引用。所以就容易理解到,这个方法就是确定新插入结点的双亲结点。也就通过此来决定新添加元素的位置。
一开始,新设一个变量result指向lastNode,即指向最后一片叶子的引用。
接下来通过判断最后一片叶子的情况来确定插入结点的双亲结点,当最后一片叶子不是根结点且同时不是左孩子的时候,就将result的父结点付给result,直到不满足两个条件之一跳出循环。当最后一片叶子是根结点时,已经确定了新结点的双亲结点,可以进入下一步,而如果最后一片叶子是右结点,就说明当前父结点是满的,不能再在当前父结点下添加新元素,所以将result指向result的父亲,方便寻找一个没有满的父结点。下一步,此时result跳出while循环,要么它是根结点,要么它是左孩子。如果它是左孩子,即进入if语句内,判断它的兄弟结点是否为null,如果返回true,那么新添加元素的双亲结点就确定了是result的父结点,而新结点将作为result的右孩子添加到堆中,如果返回false,result将指向这个右孩子,并找到它的最左下的位置添加。如果result是指向根结点的,那么也一直循环到它的最左下位置,添加新元素。
这个问题的解决参考了于欣月同学的博客,她在解释时运用了图文结合的形式,对我理解该问题起了很大帮助


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

  • 问题1:测试LinkedHeap类,实现层序输出、前序中序后序各种输出,很不巧的是它出现了乱码的情况
  • 问题1解决方案:这个问题的出现充分说明我还没能掌握迭代器的精髓,首先方法的使用就是完全错误的,我还把它当作简单的toString方法在加以使用。所以自然输出不来需要的结果,标准的应该是如图,先设置一个迭代器的对象,通过for循环一个一个调用迭代器里的内容,如图

代码托管

上周考试错题总结


  • In removing an element from a binary search tree, another node must be ___________ to replace the node being removed.
    A .duplicated
    B .demoted
    C .promoted
    D .None of the above
  • 解析:从二叉查找树中删除一个元素时,必须推选出另一个结点来代替要被删除的那个结点
    。demoted意思是降级的,promoted是升级的,从概念来看,替代元素应该是该结点的中序后继者,所以该是c。

  • The Java Collections API provides two implementations of balanced binary search trees, TreeSet and TreeMap, both of which use a ___________tree implementation.
    A .AVL
    B .red/black
    C .binary search
    D .None of the above
  • 这好像是13章的内容乱入了吧,TreeSet和TreeMap类使用的是红黑平衡二叉查找树

  • The best comparison sort in terms of order is:
    A .O(1)
    B .O(n)
    C .O(log(n))
    D .O(nlog(n))

  • Linear search has logarithmic complexity, making it very efficient for a large search pool.
    A .true
    B .false
  • 线性查找具有线性时间复杂度O(n)。

  • Bubble, Selection and Insertion sort all have time complexity of O(n).
    A .true
    B .false
排序方法 时间复杂度
选择排序 O(n^2)
插入排序 O(n^2)
冒泡排序 O(n^2)

  • Insertion sort is an algorithm that sorts a list of values by repetitively putting a particular value into its final, sorted, position.
    A .true
    B .false
  • 插入排序通过反复地将某一特定值插入到该列表的某个已排序的子集中来完成对列表值的排序。每一个值只需要插入一次,而不是重复地插入。

结对及互评

  • 博客中值得学习的或问题:

  • 基于评分标准,我给谭鑫的博客打分:8分。得分情况如下:
    正确使用Markdown语法(加1分)
    模板中的要素齐全(加1分)
    教材学习中的问题和解决过程, 三个问题加3分
    代码调试中的问题和解决过程, 三个问题加3分
  • 基于评分标准,我给方艺雯的博客打分:8分。得分情况如下
    正确使用Markdown语法(加1分):
    模板中的要素齐全(加1分)
    教材学习中的问题和解决过程, 两个问题加2分
    代码调试中的问题和解决过程, 四个问题加4分
  • 本周结对学习情况
    • 20172305
    • 20172314
    • 结对学习内容
      • 堆、实验二
  • 上周博客互评情况

其他

这周的教材学习比较容易,所以花的时间相对较少,但是实验令人难受。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 0/0 1/1 8/8
第二周 470/470 1/2 12/20
第三周 685/1155 2/4 10/30
第四周 2499/3654 2/6 12/42
第六周 1218/4872 2/8 10/52
第七周 590/5462 1/9 12/64
第八周 993/6455 1/10 12/76
第九周 1192/7467 2/12 10/86

参考资料

原文地址:https://www.cnblogs.com/Lewandodoski/p/9939739.html

时间: 2024-11-08 23:39:44

20172323 2018-2019-1 《程序设计与数据结构》第八周学习总结的相关文章

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

20172323 2018-2019-1 <程序设计与数据结构>第一周学习总结 教材学习内容总结 第一章--概述 1.1 软件质量 软件工程(Software Engineering)是一门关于高质量软件开发的技术和理论的学科. 解决的问题:控制开发过程,实现高质量的软件 软件工程的目标 高质量软件的特征 1.2 数据结构 数据结构:计算机存储.组织数据的形式. 程序 = 数据结构 + 算法 软件 = 程序 + 软件工程 栈会颠倒数据的顺序,而队列可以保持数据的顺序. 第二章--算法分析 算法

20172305 2017-2018-2 《程序设计与数据结构》第一周学习总结

20172305 2017-2018-2 <程序设计与数据结构>第一周学习总结 教材学习内容总结 本书的第一章简单的介绍了计算机和JAVA的历史,基础内容很多,代码的讲解还没用正式进入,本周一直在做敲代码的准备,简单敲了老师给的"Hello World!"以及书后的PP1.3.PP1.4等简单的小程序. 教材学习中的问题和解决过程 问题1:三种不同类型的错误,运行错误和逻辑错误的混淆 问题1解决方案:针对EX1.20的"希望做加法时却做里乘法"进行了网上

20172314 2017-2018-2 《程序设计与数据结构》第一周学习总结

20172314 2017-2018-2 <程序设计与数据结构>第一周学习总结 教材学习内容总结 本书第一章为计算机系统概述,前面是一些计算机相关的基础知识,让我对计算机有了一个总体的认识,不再是一片空白了,对主存储器和CPU影响深刻,主存储器用于保存程序和数据,CPU执行程序指令.在接下来的Java编程语言与程序开发部分,开始看的时候有点迷茫,不是很理解,后来先按照作业中附带的流程完成一些代码托管之后,接触了完整的简单的程序之后,再回过头来看书,看到的一些陌生的名词在脑海中就有了实际的对应,

20172317《程序设计与数据结构》第一周学习总结

20172317 2017-2018-2 <程序设计与数据结构>第一周学习总结 教材学习内容总结 重新温习了一遍计算机的基础 总算了解了局域网广域网因特网万维网这些东西之间的区别了 通过URL的例子知道了网址各个部分的含义 对Java编程语言和程序开发有了一个粗浅的了解 教材学习中的问题和解决过程 问题:练习题SR1.13出现了答案与题目不相符的情况 问题解决方案:题中有个选项是"网卡",答案中没有,反而有个题目没有的选项"调制解调器"(俗称"

20172322 2017-2018-2 《程序设计与数据结构》第二周学习总结

20172322 2017-2018-2 <程序设计与数据结构>第二周学习总结 教材学习内容总结 了解了print与println的区别 了解了字符串的拼接可以用+来完成 了解了转义字符的使用 学会了使用赋值 学会使用部分算术运算符 学会了使用Scanner来实现交互性 教材学习中的问题和解决过程 问题1:在最初接触赋值时对foalt和double的赋值范围不了解 问题1解决方案:使用万能的度娘后看到一个高赞答案后有了了解 问题2:在提前预习时看到2.7图形后敲入的代码无法执行 问题2解决方案

20172328《程序设计与数据结构》第二周学习总结

20172328李馨雨<程序设计与数据结构>第二周学习总结 又到周五,李馨雨同学要开始写博客了.让我们开始吧!(????) 教材学习内容总结 1.首先是String类定义的字符串,然后是print和println的区别.转义字符的学习.(让我印象深刻的\b[回车符]在字符串结尾不显示哈哈,及其更新的\t[换行符],还有在课堂上真正明白了什么是回车.) 2.了解变量.常量.赋值语句.变量:保存数据的内存单元.常量:坚定自己不会变的数据!除非你用java的反射(有点复杂,改权限.去修饰符等等.没实

20172327 2017-2018-2 《程序设计与数据结构》第二周学习总结

20172327 2017-2018-2 <程序设计与数据结构>第二周学习总结 教材学习内容总结 字符串的拼接和转义序列的使用 变量的声明和使用 讨论语法及表达式的处理 定义数据转换类型和实现类型转换的机制 创建Scanner类 教材学习中的问题和解决问题 暂无 代码学习中的问题和解决过程 问题1:在提交过程中,突然遇到无法上传的情况 问题2解决方案:通过上网查找,输入git pull之后弹出一个编辑框,选择关闭之后,再次用git push就成功了. 问题2:在按照例题2.10打代码时,Jav

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

学号20172328<程序设计与数据结构>第九周学习总结 教材学习内容总结(异常和递归) 第11章:异常 1.[异常处理]: 一个异常:是一个定义非正式情况或错误的对象,由程序或者运行时环境抛出,可以根据需要捕获和处理. 错误:错误类似于异常,但是错误代表不可恢复的问题并且必须捕获处理. 2.[处理异常的三种方法]:①根本不处理异常②当异常发生时处理异常③在程序的某个位置集中处理异常. 3.[未捕获的异常]:如果程序中不处理异常,则程序将非正常的终止运行,并产生关于描述在何处发生什么异常的信息

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

学号 20172326 <程序设计与数据结构>第九周学习总结 教材学习内容总结 异常(exception):定义非正常情况下或错误的情况的对象,由程序或运行时环境抛出,可根据需要进行相应的捕获处理. 异常与错误的区别:错误代表不可恢复的问题并且必须捕获处理.而异常可以忽视,或者使用try语句处理,或调用更高级的方法. 可检测异常与不可检测异常:可检测异常必须由方法捕获,或者必须在可能抛出或传递异常方法的throws子句中列出来.在方法定义的声明头中追加一条throws子句.不可检测异常不需要使

20172322 2017-2018-2 《程序设计与数据结构》第九周学习总结

20172322 2017-2018-2 <程序设计与数据结构>第九周学习总结 教材学习内容总结 异常 学会了使用try-catch来实现未捕获的异常的处理.可以使得异常被捕获进而不导致程序出现错误退出.使用try写入可能产生异常的语句,使用catch来编写在捕获异常后继续执行的代码(可以为空). "未捕获的异常"指在编译过程中不会被编译软件显示异常但是在运行时会出现异常导致程序直接退出,例如:"ArithmeticException"."In