20172304《程序设计与数据结构》第八周学习总结
20172304 《程序设计与数据结构》第八周学习总结
教材学习内容总结
本周主要学习的内容是堆。堆是二叉树的扩展
什么是堆
堆就是具有两个附加属性的一棵二叉树
1.它是一棵完全树。
2.对每一结点,他小于或等于其左孩子和右孩子(最小堆)最大堆与最小堆相反。
堆的操作
操作 | 说明 |
---|---|
addElement | 将给定元素添加到该堆中 |
removeMin | 删除堆的最小元素 |
findMin | 返回一个指向堆中最小元素的引用 |
addElement操作
方法将给定的元素添加到堆中恰当的位置处,且维持该堆的完全性属性和有序属性。如果给定的元素鄙视Comparable的,则该方法将抛出一个ClassCastException异常。
至于他一开始进行的插入的原则类似于层序遍历的顺序。如果新结点小于其双亲则将它们互换。我们沿着树向上继续这一过程,直至该心智要么是大于其双亲要么是位于该堆的根处。通常我们会对最末一片叶子结点进行跟踪。
堆的插入点(图中虚线部分)
堆的插入和重排序
removeMin操作
removeMin操作将删除最小堆中的最小元素并返回它。而一旦根结点被删除,那么就要使用最后一片叶子结点来代替它。然后对整个堆进行重排序,使其符合堆的性质。具体实现方法为将该新根的元素与其较小的孩子进行比较,且如果孩子更小则将它们交换,沿着树乡下继续这一过程,直至该元素要么位于某一叶子结点中,要么比它的两个孩子都小。
堆中最末一片叶子的例子(颜色为黄色的部分)
堆的删除和重排序
findMin操作
findMin方法将返回一个指向该最小堆中最小元素的引用。由于该元素总是被储存在该树的根处,所以事先这一方法只需通过返回储存在在根处的元素即可。
使用堆:优先级队列
用链表实现堆
用数组实现堆
教材学习中遇见的问题
问题:在看教材代码时看到用堆实现优先级队列时突然蒙住了,不懂得是什么意思。
解答:后来经过了多次的思考以及结合教材上的解读,终于捋清了,教材上提供了两个类一个是PrioritizedObject类,一个是PriorityQueue类。前面那个类可以近似看成是结点类,定义了要输入对象的优先级,输入的次序以及储存的方法等。这些都不是最重要的,最重要的是它重写了一个compareTo方法,通过将自身的优先级与传入的对象的优先级进行比较来返回正负值。如果优先级相同,就对阶进行比较。一开始我不懂的是第二个类中的几行代码。
public void addElement(T object, int priority)
{
PrioritizedObject<T> obj = new PrioritizedObject<T>(object, priority);
super.addElement(obj);
}
注:第二个类继承了ArrayHeap类
一开始我不理解的是既然构造函数声明了两个变量,而且在ArrayHeap类中的Comparable实例化的对象可以对任何数据进行比较大小,为什么object不会干预到正常的比较呢?
后来我在ArrayHeap中看见了这样的代码
(Comparable)tree[left]).compareTo(tree[right]) < 0
以及在PriorityQueue类的头中看见了这样的代码
ArrayHeap<PrioritizedObject<T>>
再联想到在PrioritizedObject中重写的comapreTo方法
public int compareTo(PrioritizedObject obj)
{
int result;
if (priority > obj.getPriority())
result = 1;
else if (priority < obj.getPriority())
result = -1;
else if (arrivalOrder > obj.getArrivalOrder())
result = 1;
else
result = -1;
return result;
}
就知道了在第二个类中引用的ArraryHeap类中定义的是第一个类,所以在进行Comparable是使用的实际上是在第一个类中重写的copareTo方法。即先按照优先级进行排序然后在按照先进先出的顺序进行排序。
代码调试中的问题和解决方案
问题:在进行pp12.1时,出现了异常
解答:后来发现是在改代码时忽略了图中第十行代码在Comparable后面的方括号中没有将原来的PrioritizedObject改为PrioritizedObject1,所以出现了类型无法转换的错误。
代码托管
(statistics.sh脚本的运行结果截图)
上周考试错题总结
无
博客互评
20172304郭恺郭恺同学能对教材的内容进行合理的总结又能将树中不懂得知识点分析的如此淋漓尽致。
20172328李馨雨李馨雨同学的博客内容充实,排版美观,条理清晰,是不可多得的博客。
点评过的同学博客和代码
- 上周博客互评情况
20172304郭恺郭恺同学的博客依然是一如既往的优秀,既将教材中的内容总结的详略得当,还能具体而全面的对自己的错误进行总结和提升。
20172328李馨雨李馨雨同学的博客还是很认真的。
其他(感悟、思考等,可选)
本周学习了堆的相关知识,堆是建立在二叉树基础上的一种数据结构,所以实现和理解起来比较容易。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 30/30 | 1/1 | 10/10 | |
第二周 | 766/796 | 1/2 | 40/50 | |
第三周 | 817/1613 | 1/3 | 20/70 | |
第四周 | 1370/3983 | 2/5 | 30/100 | |
第五周 | 1235/5214 | 1/6 | 10/110 | |
第六周 | 1328/6542 | 1/7 | 20/130 | |
第七周 | 1218/7860 | 1/8 | 20/150 | |
第八周 | 585/9445 | 1/9 | 20/170 |
参考资料
1.蓝墨云班课
2.java软件结构与数据结构