20172322 《程序设计与数据结构》第八周学习总结
教材学习内容总结
本章的内容主要讲堆的知识,而所谓堆就是一种具有一些特殊属性的树,就像二叉查找树一样。而堆也有两种分类,分别是
-
最大堆
-
最小堆
但是无论是最大堆还是最小堆的第一个特殊属性均为:
- 堆必须是一棵完全树。
第二个特殊属性是:
- 对于每一个结点,它小于或等于/大于其左右孩子。
但本章的内容主要以最小堆为例,学会了最小堆可以类比退出最大堆的性质。
因为堆是一种含有特殊属性的树,所以在本章中堆继承了以前二叉树的所有性质,本章仅仅是在BinaryTreeADT
基础上添加了addElement
、removeMin
、findMin
方法。
addElemnt
方法:因为堆是一个完全树,所以说所添加元素的位置必定为堆的最后一层或最后一层之后的左边第一个位置。但在添加元素后还需要考虑整个堆的属性是否保持完成,所以说需要考虑重新排序。removeMin
方法:删除堆的根结点后重新排序。findMin
方法:简单的返回根结点的操作。
与以往类似,本次分别利用链表和数组实现堆。
-
链表实现堆:创建
HeapNode
类继承BinaryTreeNode
类,但由于BinaryTreeNode
无双亲结点的存在,所以在HeapNode
中添加了一个双亲指针。(值得注意的是,添加双亲结点的原因是:在我们插入元素之后我们需要向上遍历该树,所以必须存在一个指向双亲的指针)addElement
方法的复杂度是O(logn),与此方法同时存在的是getNextParentAdd
和heapifyAdd
方法,他们用于返回插入结点的双亲的引用和对添加元素后的堆进行重排序。removeMin
方法的复杂度同为O(logn),与此方法同时存在的是getNewLastNode
和heapifyRemove
方法,他们用于返回新插入的节点和对删除元素后的堆进行重排序。findMin
方法:return root.element
-
数组实现堆:与二叉树相同,对于任一结点n,n的左孩子将位于数组的2n+1位置处,n的右孩子将位于数组的2(n+1) 处,而对于任一非根结点m,m的双亲结点位于 (n-1)/2处,这意味着我们利用数组实现堆不需要建立一个
HeapNode
类。- 利用数组实现堆的
addElement
、removeMin
、findMin
方法的解释与利用链表实现堆类似,个人觉得无需过多言语。
- 利用数组实现堆的
-
堆排序:这是一种全新的排序算法。这种排序算法完全是根据堆的性质而思考出来的排序算法。以最小堆为例,每次将根结点与最后一个结点互换后,将最后一个结点提出树,这样就得到了一个最小的元素。在提出最小结点过后对树重新排序,之后重复以上两步操作直到排序完成。如图所示:
教材学习中的问题和解决过程
本章的内容就是对之前内容的简单拓展,实在是找不到什么问题。如果真的要我找一个问题就是:
- 问题一:在书P265中偏下部有一句话“n的右孩子将位于数组的2(n+1)位置处当然,反过来......”,这句话一读就有问题。
- 问题一解决方案:这句话应该为“n的右孩子将位于数组的2(n+1)位置处,当然反过来......”
代码调试中的问题和解决过程
- 问题一:在完成PP12.1时,自己最初只是简单的以为利用书上的优先队列的代码就可以完成,但是这好像是我没有认真读题。
- 问题一解决方案:在结对伙伴范雯琪提醒下,自己重写了队列,在书上优先队列
PriorityQueue
的基础上删除了实现优先级的代码,就实现啦。
代码托管“点这里跳转到码云”
上周考试错题总结
-
错题1:A binary search tree is a binary tree with the added property that the left child is greater than the parent, which is less than or equal to the right child.
-
A.True
-
B.False
-
错题1解析:二叉排序树或者是一棵空树,或者是具有下列性质的二叉树,
- 若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 左、右子树也分别为二叉排序树;
- 没有键值相等的节点。
-
错题2:A binary search capitalizes on the fact that the list is not sorted.
-
A.True
-
B.False
-
错题2解析:二叉查找树正式利用列表是被排序过才能进行搜索。
-
错题3:A binary search can only be performed if the search pool is sorted.
-
A.True
-
B.False
-
错题3解析:当查找池被排序好了以后就只能利用二叉查找树来搜索。
结对及互评
- 博客中值得学习的或问题:
- 范雯琪同学的博客课本上的学习内容总结部分写得十分详细,值得学习。
- 范雯琪同学在博客中展示的图都很直观。
- 代码中值得学习的或问题:
- commit提交的解释清晰明了,我觉得我应该学习。
点评过的同学博客和代码
- 本周结对学习情况
-
结对学习内容
- 她提醒了我的PP12.1有点问题,感谢。
其他
- 感悟:这周的知识仅仅是之前知识的一点点拓展,不难,但是也需要认真对待。
课本单词
(本部分用于收集本章节后的生词)
- heap:堆
- minheap:最小堆
- maxheap:最大堆
- complete binary tree:完全二叉树
- priority tree:优先树
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 0/5000 | 2/2 | 8/8 | 认真学习!积极向上 |
第二周 | 812/812 | 1/3 | 22/30 | |
第三周 | 814/1626 | 1/4 | 20/50 | |
第四周 | 1386/3012 | 2/6 | 20/70 | 愉快的国庆节就要结束了... |
第五周 | 1222/3234 | 1/7 | 30/100 | |
第六周 | 1327/4561 | 2/7 | 30/100 | 啦啦啦啦啦 |
第七周 | 1170/5631 | 1/8 | 33/133 | |
第八周 | 1250/6881 | 2/10 | 30/163 |
-
计划学习时间:25小时
-
实际学习时间:30小时
-
改进情况:根据学姐的建议改进了commit。