CS61B - Lec 25 - Heaps, Priority Queue

Lec 25 - Heaps, Priority Queue


今天我们要实现的是这样的功能:
在这里插入图片描述
主要就是getSmallest和removeSmallest,keep track of the smallest item。这有什么用呢?

比如,接受了很多message输入,并且有一个对message和谐程度的排序方法HarmoniousnessComparator,要求选出最不和谐的M条message。
在这里插入图片描述
我们可以建一个list,存储所有消息,然后整体排序:
在这里插入图片描述
但是这样需要O(N)的内存空间。然而如果标记了最和谐(小)的message,就可以:接收message - 如果size > M,removeSmallest,这样就剩下最不和谐的M条message,并且能保证使用的内存空间一直是O(M)。

Heaps

在这里插入图片描述
Heap是一种新的Tree类型。和BST不同的是,它的父节点必须小于等于两个子节点,并且只能在最底层缺失右边的leaf。
在这里插入图片描述
所以,显而易见,getSmallest方法很好实现,直接返回根节点。add和removeSmallest就比较麻烦了。
在这里插入图片描述
如上图,想要add(3),那就把3插在最底层的?位置,然后不断与上面的节点交换,最终到达符合规则的位置。最后3被加在第二行5的位置,?位置是5。
removeSmallest就要把最底层的8和放到最上方,remove根节点1,然后不断把8和下面的节点交换,直到满足规则。
在这里插入图片描述

Tree Representations

如何实现Tree的结构?

  1. Mapping

1a: 一个根节点指向若干子节点
在这里插入图片描述
1b: 一个根节点包含一个子节点的数组
在这里插入图片描述
1c: 根节点包含一个子节点,子节点再包括一个同级的子节点
在这里插入图片描述
个人感觉这三种方法大同小异。。。没什么卵用。

  1. Array

2a: 用一个array存储key,一个array存储parents,和之前的UnionFind一样
在这里插入图片描述
但是通过观察节点编号,发现是有一定规律的。

2b: 只用一个array存储key,parents可以计算得出
在这里插入图片描述
parent(k) = (k - 1) / 2,验证发现确实是这样。找找规律。有一个小问题是0的parent算出还是0。

2c: 类似于sentinel,在2b的基础上建一个空节点,计算parent(k)变成了k / 2
在这里插入图片描述
总结+分析复杂度。除了getSmallest,add和remove还是需要遍历树的高度,所以也有log(N)的复杂度,但是和Array, BST比起来仍然是最优,HashTable是无序的,对查找最小并无卵用。
在这里插入图片描述

Data Structures Summary

总结一下之前学过的所有数据结构。重点是里面包含的ADT的思想,同样的功能可以用不同的核心数据结构来实现,效率也不同。这就是ADT的意义吧。
在这里插入图片描述

发布了20 篇原创文章 · 获赞 0 · 访问量 170

猜你喜欢

转载自blog.csdn.net/fourier_transformer/article/details/105509257