查找数组 min-heap 中所有小于 x 的键
有人可以描述一种在最小堆的数组实现中找到所有小于 x 的键的算法吗? 我希望运行时间至少为 O(k),其中 k 是报告的键数。
我已经为此摸不着头脑有一段时间了。
Can some one describe an algorithm that finds all keys smaller than x in an array implementation of a min-heap.
I want the running time to be at least O(k) where k is the number of keys reported.
I've been scratching my head for a while now with this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
对于树最小堆有一个简单的递归算法:
如果子树的根具有大于或等于 x 的值,那么根据最小堆的定义,其所有后代也将具有大于或等于 x 的值等于x。该算法不需要比其遍历的项目更深入地探索,因此它是 O(k)。
当然,将其转换为数组算法是一件微不足道的事情:
There is a simple recursive algorithm for a tree min-heap:
If a subtree's root has a value that is greater than or equal to x, then, by definition of a min-heap, all of its descendants will also have values greater than or equal to x. The algorithm need not explore deeper than the items its traversing, hence it is O(k).
Of course, it's a trivial matter translating this to an array algorithm:
要获得“至少”某事物的运行时间并不那么困难,我认为您的意思是“最多”。
不幸的是,最小堆除了最小值之外不太擅长查找其他值。
您可以对堆的树视图进行
宽度优先深度优先扫描,并终止到达X的每个分支。这将是O(k),但很复杂。要找到 Y <= X 的所有 Y,您不妨扫描整个数组,这将是 O(n),但开销要少得多。
选择取决于 n/k 比率
To get a running time of 'at least' something is not so difficult, I assume you mean 'at most'.
Unfortunately, a min-heap is not very good at finding anything else than the smallest value.
You can do a
breadth-firstdepth-first scan of the tree-view of your heap, and terminate every branch where you have reached X. This will be O(k), but complicated.To find all Y where Y <= X you might as well scan the entire array, this will be O(n) but with much less overhead.
The choice depends on the ratio n/k
作为数组的实现是无关紧要的,您仍然可以进行自上而下的树搜索。只是不需要使用“经典”指针,您需要计算相应的子节点索引。
这样就可以从顶部开始递归搜索,并在当前节点大于 x 的每个分支上停止递归。这通常会删除许多您不需要检查的值。
对于 k 个返回值,O(k) 显然是最好的情况。如果您的顶部节点 <= x,您将立即开始获得结果。如果它更大,则完成 - 结果为空。
从那里你可以得到子树一直向下的结果,直到你到达值>的分支。 x。您最多需要执行 2*k 检查来修剪这些分支,所以在我看来总共是 O(k) 。
The implementation as array is irrelevant, you can still do a top-down tree-search. Just instead of using the "classic" pointers, you need to calculate the respective child-node indexes.
With that out of the way do a recursive search from the top and stop recursing on each branch where the current node is greater than x. That will in general prune away a lot of values you don't need to check.
With k return values O(k) is obviously your best case. If your top node is <= x, you start getting results right away. If its greater, you are done - the result is empty.
From there you get results all the way down the subtree until you hit branches with values > x. You need to do at most 2*k Checks to prune those branches, so it looks like O(k) in total to me.