实现支持各种操作的数据结构

时间:2014-03-01 20:33:55

标签: c++ algorithm data-structures stl

我必须实现一个支持以下三个功能的数据结构。数据是两个双值的对(a,b),数据集中在特定区域。让我们说'a'的值在500-600范围内。

  1. 插入(双a,双b) - 在数据结构中插入数据,一对(双,双)。如果该对的第一个元素已存在,则将其第二个元素更新为新值。

  2. 删除(双a) - 删除包含第一个元素的数据= a。

  3. PrintData(int count) - 打印具有第count个最大值的数据的值。根据data.first比较价值。

  4. 输入文件包含一系列Insert,Delete和PrintData操作。目前,我已经使用STL-Map将数据结构实现为高度平衡的二进制搜索树,但速度不够快。

    是否还有比Map更快的其他实现。 我们可以使用缓存来存储最常见的PrintData查询。

2 个答案:

答案 0 :(得分:2)

我建议使用2个二叉搜索树(BST) - 一个是从ab的地图(按a排序),另一个应按{{1}排序}}

第二个需要是自定义BST - 您需要让每个节点以root身份存储子树中节点数量的计数 - 这些计数可以在O(log n)中更新,并且将允许O(log n)查询获得第k个最大元素。

进行插入操作时,您只需先在第一个BST中查找b的值,然后从第二个BST中删除该值,然后更新第一个值并将新值插入第二个。

对于删除,您只需在第一个BST中查找b的值(并删除该对),然后从第二个BST中删除该值。

所有提到的操作都应该采用O(log n)。

<强>缓存

例如,如果您只查询前10个元素,则可以维护另一个仅包含10个元素的BST(或者甚至只是一个可选排序的数组,因为只有10个元素),我们将然后查询而不是上面的第二个BST。

插入时,如果值大于最小值,也插入此结构中,并删除最小值。

删除时,我们需要查找下一个最大值并将其插入到小BST中。虽然这也可以懒惰地进行 - 当移除时,只需将其从此BST中移除 - 不要再将其填充到10。在查询时,如果此BST中有足够的元素,我们可以只使用这个查找,否则我们会找到填充此BST所需的大BST中的所有值,然后我们进行查询。

这将导致最佳情况O(1)查询(最坏情况O(log n)),而其他操作仍然是O(log n)。

虽然增加的复杂性可能不值得 - 但O(log n)非常快,即使对于大的n也是如此。

基于这个想法,我们只能将这个小BST与BST映射b映射到a - 这需要我们检查所有值以找到在删除后的查询过程中需要的那些,所以如果没有大量的删除,它将真正有用。

答案 1 :(得分:2)

我会推荐一个indexed skip list。这将为您提供O(log n)插入和删除,以及O(log n)访问第n个最大值(假设您按降序维护列表)。

跳过列表并不比自平衡二叉树更难实现,并且在某些情况下可以提供更好的性能。值得考虑。

original skip list paper