Minheap的Topk

时间:2018-11-01 01:00:34

标签: algorithm

如果将数据点保留在最小堆(A)中,则我的应用程序效率最高。但是,作为结束步骤,我想从A输出TopK。

作为起点,将A的数据点从前到后添加到另一个minheap(B),并填充K个数据点后,拒绝小于根数的数据点将以相反的顺序提供TopK列表。

我想知道是否需要从后到前完全通过A,还是在完成至少提供了K个数据点的行(意味着树的深度)之后可以停下来吗?

我知道有些算法可以将minheap转换为maxheap,但是我不希望对整个原始堆进行排序,而只是对TopK进行排序。

预先感谢

2 个答案:

答案 0 :(得分:0)

您需要考虑底部log_2(K)个完整的行。然后,您可以停止操作,因为比根更近的每个项目都少于K个或更多其他项目,并且不能位于前K个。

这不会为您节省很多工作,因为堆中至少有一半的项目是叶子。

答案 1 :(得分:0)

N =基于1的Minheap A的大小

我认为最有效的算法如下:

  1. 使用已知的使用大小为K的Minheap B的TopK流式传输TopK的算法来计算叶子节点(N / 2 + 1到N)的暂定TopK(例如:http://stevehanov.ca/blog/index.php?id=122)。 / p>

  2. 标识构成TopK的节点A中的索引,然后递归检查其父级以查看它们是否构成TopK。递归的深度受底部log2(K)完整行的索引约束,如Matt所指出的那样。

在实践中,我发现它通常检查N / 2 + K个节点,尽管退化的情况可能会一直检查底部的log2(K)行。