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

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

概述 Generalization

本周学习了二叉树的另一种有序扩展?是什么呢?你猜对了!ヾ(◍°∇°◍)ノ゙就是堆。本章将讲解堆的链表实现and数组实现,以及往堆中添加元素或从堆中删除元素的算法;还将介绍对的一些用途,包括基本使用和优先队列。

教材学习内容总结 A summary of textbook

  • (heap)就是具有两个附加属性的一颗二叉树:
    • 第一点:它是一颗完全二叉树 ,即叶子节点都在最后一层靠左侧。
    • 第二点:对每一结点,它小于(大于)或等于其左孩子和右孩子。
  • 第二点中满足大于的条件下形成的是一个最大堆(大顶堆),反之则为最小堆(小顶堆)
  • 最小堆将其最小元素存储在该二叉树的根处,且其跟的两个孩子同样还是最小堆。
  • 堆中的操作:
    1332971-20181110153342605-1476200578.png

  • addElement操作
    • addElement方法将给定的Comparable元素添加到堆的恰当位置处,且维持该堆的完全性属性和有序属性。

      • Little Tip:完全树你还记得吗?完全二叉树就是所有叶子都位于h或者h-1层,其中h为log2(n),且n为树中的元素数目,h层的所有叶子都位于该树的左边,那么该树被认为是完全的。
    • 堆就是一棵完全的二叉树,所以对于插入的新结点只存在一个正确的位置。要么是h层左边的下一个空位置,要么是h+1层左边的第一个位置(如果h层为满的话)。
    • 将新结点定位到正确的位置后,我们就必须对这个堆进行排序来保持其有序属性。方法就是对树中的最末一片叶子进行跟踪记录,在一个addElement方法后,最末结点就被设定为插入结点。也就是通过上溯树来保证树的有序性.
  • removeMin操作
    • removeMin方法将删除最小堆中的最小元素并返回它,由于最小元素是存储在最小堆的根处,所以我们需要返回储存在根处的元素并用堆中的另一元素替换它。
    • 要维持该树的完全性,就是把储存在树中最末一片叶子上的元素用来替换根元素。
    • 将存储在最末一片叶子上的元素移动到根处,就必须对该堆进行重新排序来维持该堆的排序属性。
    • 要维持该堆的排序属性,就要从根结点下溯树。具体过程是将该新根元素与其较小的孩子进行比较,且如果孩子更小就将它们互换,沿着树向下继续这一过程,直至该元素要么位于某一叶子中,要么比它的两个孩子都小。
  • findMin操作
    • findMin将返回一个指向最小堆中最小元素的引用,由于最小堆的最小元素就在根处,所以直接返回存储在根处的元素即可。
  • 使用堆——堆排序heapSort
    • 堆排序是对简单选择排序的一种改进。
    • 改进着眼点:如何减少关键字的比较次数
      • 简单选择排序在一趟排序中仅选出最小关键字,但是没有把一趟比较结果保存下来,因而比较次数较多。
      • 堆排序在选出最小关键字同时,也找出较小的关键字,从而减少了后面选择中的比较次数,提高了整个排序效率。
  • 左右子树都是大顶堆,如何调整根结点,使得整棵树成为一个堆?
    1332971-20181110153429106-440613040.png
  • 堆调整 —— 筛选过程
    • 调整过程中,总是将根结点(被调整结点)与左右孩子比较;
    • 不满足堆条件时,将根结点与左右孩子中较大者交换;
    • 这个调整过程一直进行到所有子树都是堆或者交换到叶子为止。
    • 这个从堆顶到叶子的调整过程称为“筛选”。
  • 对堆进行筛选完毕之后我们就要为保持其有序性而开始排序。
  • 堆排序-排序过程
    1332971-20181110153455796-969315280.png
    1332971-20181110153503796-181301810.png
    1332971-20181110153511397-646248335.png
    • 从无序序列的第[n/2]个元素开始(对应于完全二叉树的最后一个非终端结点)进行筛选;
    • 当解决一个非终端结点(非叶子结点)的有序问题后,把此非终端结点看做一个叶子,然后继续上溯,找到倒数第二个非终端结点,继续进行有序替换,知道整个堆有序为止。
  • heapSort的复杂度为O(nlogn)
  • 使用堆:优先级队列
  • 优先级队列(Priority queue)就是遵循两个排序规则的集合。
    • 首先,具有更高优先级的项目在先。
    • 其次,具有相同优先级的项目使用先进先出方法来确定其排序。

      • Little Tip:虽然最小堆根本就不是一个队列,但是它却提供了一个高效的优先级队列实现。
  • 用链表实现堆
    • 因为我们要求在插入元素后能够向上遍历该树,所以堆中的结点必须存储在指向其双亲的指针。所以我们从创建一个HeapNode类开始我们的链表实现,该类对BinaryTreeNode进行了拓展并添加了一个双亲指针。
    • 链表实现的实例数据由指向HeapNode且称为lastNode的单个引用组成,这样我们就能够跟踪记录该堆中最末一片叶子。public HeapNode lastNode;
    • addElement操作:
      • 在恰当的位置添加一个新元素
      • 对堆进行重排序以维持其排序属性
      • 将lastNode指针重新设定指向新的最末结点
    • removeMin操作:
      • 用存储在最末结点处的元素替换存储在根处的元素
      • 对堆进行重排序
      • 返回原始的根元素
    • findMin操作:
      • 该方法仅仅返回一个指向存储在堆根处元素的引用,因此复杂度为O(1)。
  • 用数组实现堆
    • 用数组实现堆不再需要创建一个HeapNode类对,而是通过用数组来保存堆中的数据。
    • 在二叉树的数组实现中,树的根位于位置0处,对于每一结点n,n的左孩子将位于数组的2n+1处,右孩子将位于数组的2n+2处。
    • addElement操作:
      • 在恰当的位置添加一个新元素
      • 对堆进行重排序以维持其排序属性
      • 将count递增1.
    • removeMin操作:
      • 用存储在最末结点处的元素替换存储在根处的元素
      • 对堆进行重排序
      • 返回原始的根元素
    • findMin操作:
      • 返回指向存储在堆的根处或数组0位置处的元素。
  • 总结:链表实现和数组实现的addElement方法和removeElement方法时间复杂度都是O(logn)。但是,数组的实现还是更高效一些,因为在addElement操作中数组实现不用去确定插入双亲的结点,在removeElement操作中数组实现不需要确定新的最末一片叶子。

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

  • 问题1:周四晚上看用链表实现堆的添加操作代码。刚刚看懂小伙伴仇夏来找我讨论,讨论了一会瞬间觉得自己没有真正看懂,那段奇妙的代码如下:
private HeapNode<T> getNextParentAdd(){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();}elsewhile (result.getLeft() != null)result = (HeapNode<T>)result.getLeft();return result;}

这段代码是返回将要插入结点的双亲结点的方法,当时我和仇夏讨论的是有两种情况。因为我们知道插入操作为了保证树的完全性,所以要在h层的从左开始数的第一个空结点插入或者在h+1层的最左边插入(如果树是满的话),但是在循环体中不满足我们的要求。

  • 问题1的解决:
  • 问题的重点是“下一个将要插入结点的双亲结点”,之前一直理解的是新插入结点的双亲结点,所以当然不对。在理解正确之后,画出几种插入的可能情况,再跟着上述代码理解几遍,就慢慢清晰明朗了。
    1332971-20181110153639776-14310583.jpg

  • 问题2:之前在学习栈的时候感觉一直在和堆一起被提起,所以堆和栈之间到底是什么关系?
  • 问题2的解决:
  • 简单的说: Java把内存划分成两种:一种是栈内存,一种是堆内存。
  • 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。 当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。
  • 堆内存用来存放由new创建的对象和数组。在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。
  • 堆和栈的区别比较:
    • 1.栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。
    • 2.栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享,详见第3点。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。
    • 3.Java中的数据类型有两种。 一种是基本类型(primitive types), 共有8种,即int, short, long, byte, float, double, boolean, char(注意,并没有string的基本类型)。这种类型的定义是通过诸如int a = 3; long b = 255L;的形式来定义的,称为自动变量。值得注意的是,自动变量存的是字面值,不是类的实例,即不是类的引用,这里并没有类的存在。如int a = 3; 这里的a是一个指向int类型的引用,指向3这个字面值。这些字面值的数据,由于大小可知,生存期可知(这些字面值固定定义在某个程序块里面,程序块退出后,字段值就消失了),出于追求速度的原因,就存在于栈中。

代码实现时的问题作答 Exercise

  • 问题1:用堆实现队列?树中给的堆是由数组和链表实现的,那么我们应该用ArrayHeap还是Linkedheap实现呢?又该如何实现?
  • 问题1的解决:首先,我们知道在第十章中队列的实现可以由链表或者循环数组实现,并且堆可以由链表和数组实现,因此是否可以推出队列可以由数组实现的堆或者链表实现的堆来实现呢?
  • 首先,我先用链表实现的堆来实现队列。通过在enqueue方法中调用addElement方法,就能够实现队列的入队,但是在入队后进行了堆的插入中的排序?队列是符合先进先出原则的,那么我就修改了堆中的插入方法,将其中的排序删掉。同理,当出队时也不应该去考虑排序的问题。但是当我删除掉删除的排序后,再执行删除队列中前两个元素,我却发现删除的并不一定是队列的前两个值,反而删除掉了最开始跟的值和最末一个叶子,这是由堆的性质决定的。所以想要保持先进先出,我们就要找到堆顶的左孩子然后删除。所以我们需要改变一下堆中的排序方法。链表的实现方法很麻烦,而且要改变删除的排序算法需要考虑很多种情况,在做了两小时还是不能完整正确的情况下,让我们把目光投向数组。
    1332971-20181110153709226-1861657092.png

  • 数组中只需要将删除后的最末结点变成null就可以达到效果。
    1332971-20181110153722436-1884810174.png

上周测试活动错题改正 Correction

  • 1.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
  • 正确答案选 B。当在二叉查找树上删除一个结点时,后面的结点需要向上移动来补全。当时,以为越靠近根结点说明深度越低,所以是降级了;但是看完答案好像人家的意思是向上补全。题意理解不准确哈哈
  • 2.In removing an element from a binary search tree, another node must be demoted to replace the node being removed.
    A .True
    B .Flase
  • 正确答案选 A ,和第一题一模一样好吗?哭
  • 3.One of the uses of trees is to provide simpler implementations of other collections.
    A .True
    B .Flase
  • 正确答案选 B 。这道题确实是我自己不太懂的。通过搜索得知,java中树的应用主要有:菜单树,还有权限树,商品分类列表也是树结构。在这几章的学习中,好像确实没有通过树来简单实现其他集合,树提供的方便性可以用于查找、排序等等。
  • 4.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
  • 正确答案选 B ,我当时选了A。我觉得还是题意理解的问题。我理解的题意是“插入排序是一种重复的将特殊值插入后面,然后排序,然后安置的算法”我觉得插入排序就是这样一个流程,所以我也不知道出现了什么问题。

码云链接

代码量(截图)

1332971-20181110153751722-1556700772.png

结对及互评Group Estimate

  • 点击进入结对小伙伴20172301郭恺的博客
  • 点击进入结对小伙伴20172304段志轩的博客

点评模板:

  • 博客中值得学习的或问题:
    • 20172301:这周的实验四完全没有思路,是最后看了郭恺同学的作业勉强理解了然后写的。所以说,佩服佩服。对链表堆和数组堆的优缺点分析的很透彻。
    • 20172304:图很多,但是排版有点混乱,不是特别美观可以继续改进。内容还是有点少,没有上周博客好哟!一起继续加油!

其他(感悟、思考等,可选)Else

Crossing miles of frustrations and rivers a raging,picking up stones I found along the way.

怕不轻松,怕太轻松。
再也不用觉得工作日长,因为每天好像都是工作日。想忙里偷闲就忙里偷闲,想抓紧做事就抓紧做事。

我将每天告诉自己:请对专业课程更加虔诚一点。

学习进度条Learning List

代码行数(新增/累积)博客量(新增/累积)学习时间(新增/累积)
目标5000行30篇400小时
第一周0/01/18/8
第二周621/6211/212/20
第三周678/12991/310/30
第四周2734/40331/420/50
第五周1100/51331/520/70
第六周1574/67072/715/85
第七周1803/85101/820/105
第八周2855/113652/1025/130

参考资料Reference

  • [Java软件结构与数据结构](第四版)
  • 堆这种数据结构
  • 让你彻底明白JAVA中堆与栈的区别
  • java数据结构:基于树的堆

转载于:https://www.cnblogs.com/LXY462283007/p/9939573.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/250272.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

javascript --- Vue初始化 模板渲染

不带响应式的Vue缩减实现 模板 现有模板如下: <div id "app"><div class"c1"><div titlett1 id"id">{{ name }}</div><div titlett2 >{{age}}</div><div>hello3</div></div><ul>…

#RANK_1 极其简单的递归——骑士与金币

2000:金币 总时间限制: 1000ms内存限制: 65536kB描述国王将金币作为工资&#xff0c;发放给忠诚的骑士。第一天&#xff0c;骑士收到一枚金币&#xff1b;之后两天&#xff08;第二天和第三天&#xff09;里&#xff0c;每天收到两枚金币&#xff1b;之后三天&#xff08;第四、…

javascript --- vue2.x中原型的使用(拦截数组方法) 响应式原理(部分)

说明 在Vue2.x中,利用了对原型链的理解,巧妙的利用JavaScript中的原型链,实现了数组的pop、push、shift、unshift、reverse、sort、splice等的拦截. 你可能需要的知识 参考 - MDN 原型链 JavaScript常被描述为一种基于原型的语言(prototype-based language),每个对象拥有一…

dubbo-admin构建报错

dubbo-admin构建报错 意思是maven库里没有dubbo2.5.4-SNAPSHOT.jar这个版本的dubbo的jar包&#xff0c;把dubbo-admin项目的pom.xml的   <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>${proje…

PyCharm 通过Github和Git上管理代码

1.Pycharm中设置如图: 2.配置Git,通过网页 https://www.git-scm.com/download/win 下载 3. 转载于:https://www.cnblogs.com/0909/p/9956406.html

享元模式-Flyweight(Java实现)

享元模式-Flyweight 享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用。 本文中的例子如下: 使用享元模式: 小明想看编程技术的书, 就到家里的书架上拿, 如果有就直接看, 没有就去买一本, 回家看. 看完了就放到家里…

013.Zabbix的Items(监控项)

一 Items简介 Items是从主机里面获取的所有数据&#xff0c;可以配置获取监控数据的方式、取值的数据类型、获取数值的间隔、历史数据保存时间、趋势数据保存时间、监控key的分组等。通常情况下item由key参数组成&#xff0c;如监控项中需要获取cpu信息&#xff0c;则需要一个对…

算法 --- 记一道面试dp算法题

题目: 给定一个数组(长度大于1),如下 let a [1,4,3,4,5] // 长度不确定,数值为整数要求写一个函数,返回该数组中,除本身数字之外其他元素的成积.即返回如下: // 过程[4*3*4*5, 1*3*4*5, 1*4*4*5, 1*4*3*5, 1*4*3*4] // 结果[240, 60, 80, 60, 48]题目要求不使用除法,且时间…

ASP.NET MVC 实现页落网资源分享网站+充值管理+后台管理(10)之素材管理

源码下载地址&#xff1a;http://www.yealuo.com/Sccnn/Detail?KeyValuec891ffae-7441-4afb-9a75-c5fe000e3d1c 素材管理模块也是我们这个项目的核心模块&#xff0c;里面的增删查改都跟文章管理模块相同或者相似&#xff0c;唯一不同点可能是对附件的上传处理&#xff0c;但…

Git很简单--图解攻略

Git Git 是目前世界上最先进的分布式版本控制系统&#xff08;没有之一&#xff09;作用 源代码管理为什么要进行源代码管理? 方便多人协同开发方便版本控制Git管理源代码特点 1.Git是分布式管理.服务器和客户端都有版本控制能力,都能进行代码的提交、合并、. 2.Git会在根…

vc/vs开发的应用程序添加dump崩溃日志转

原贴地址&#xff1a;https://blog.csdn.net/wangkui1331/article/details/78029940 vc/vs开发的应用程序出现崩溃的时候&#xff0c;由于没有任何记录&#xff0c;导致开发人员很难追踪&#xff0c;但是添加dump文件后&#xff0c;就可以免除这些烦恼 1.添加方法 &#xff08;…

51 nod 1127最短的包含字符串(尺取法)

1127 最短的包含字符串 收藏关注给出一个字符串&#xff0c;求该字符串的一个子串S&#xff0c;S包含A-Z中的全部字母&#xff0c;并且S是所有符合条件的子串中最短的&#xff0c;输出S的长度。如果给出的字符串中并不包括A-Z中的全部字母&#xff0c;则输出No Solution。Input…

JSON 数据重复 出现$ref

JSONArray 类型 如果我们往里面add数据的时候 如果数据相同&#xff0c;那么就会被替换成 $ref: 也就是被简化了 因为数据一样所直接 指向上一条数据 循环引用&#xff1a;当一个对象包含另一个对象时&#xff0c;fastjson就会把该对象解析成引用。引用是通过$ref标示的&am…

Linux初学时的一些常用命令(4)

1. 磁盘 查看当前磁盘使用情况 df -h查看某个文件大小 du -sh 文件名 如果不输入文件名&#xff0c;默认是当前目录的所有文件之和&#xff0c;即当前目录大小 2. 系统内存 free参数详解&#xff1a;https://blog.csdn.net/loongshawn/article/details/51758116 3. CPU CPU 使用…

爬虫之拉勾网职位获取

重点在于演示urllib.request.Request()请求中各项参数的 书写格式 譬如&#xff1a; url data headers...Demo演示&#xff08;POST请求&#xff09;:import urllib.requestimport urllib.parseimport json, jsonpath, csvurl "https://www.lagou.com/jobs/positionAjax.…

小程序 --- 点击放大功能、获取位置信息、文字样式省略、页面跳转(navigateTo)

1. 点击放大功能的实现 需求: 点击轮播图中的图片会实现放大预览的功能。首先有轮播图的样式如下 <!-- pages/goods_detail/index.wxml --> <!-- 轮播图 --> <view class"detail_swiper"><swiperautoplaycircularindicator-dots><swip…

Axure实现多用户注册验证

*****多用户登录验证***** 一、&#xff08;常规想法&#xff09;方法&#xff1a;工作量较大&#xff0c;做起来繁琐 1、当用户名和密码相同时怎么区分两者&#xff0c;使用冒号和括号来区分&#xff1a; eg. (admin:123456)(123456:demo)(zhang:san);由此得出前面是括号后面是…

Maximum Xor Secondary(单调栈好题)

Maximum Xor Secondary CodeForces - 280B Bike loves looking for the second maximum element in the sequence. The second maximum element in the sequence of distinct numbers x1, x2, ..., xk (k > 1) is such maximum element xj, that the following inequa…

杂项-公司:唯品会

ylbtech-杂项-公司&#xff1a;唯品会唯品会公司成立于2008年08月&#xff0c;2012年3月23日登陆美国纽约证券交易所上市&#xff08;股票代码&#xff1a;VIPS&#xff09;。成为华南第一家在美国纽交所上市的电子商务企业。主营B2C商城唯品会名牌折扣网站是一家致力于打造中高…

Linux基本的操作

一、为什么我们要学习Linux 相信大部分人的PC端都是用Windows系统的&#xff0c;那我们为什么要学习Linux这个操作系统呢&#xff1f;&#xff1f;&#xff1f;Windows图形化界面做得这么好&#xff0c;日常基本使用的话&#xff0c;学习成本几乎为零。 而Linux不一样&#xff…