我正在寻找一个适当高效的存储结构来处理按随机顺序到达的数据,但必须按指定的顺序处理和/或从堆栈中删除。
为了更清楚:
每个项目x都有一个索引i,一个时间戳t,并按如下方式处理(假设已经填充了存储结构)。
repeat
1) Process (remove) the item with the smallest time stamp.
2) Add new items (0 or more).
3) Remove (0 or more) items (referenced by their index).
until false
保证每个项目都有唯一的时间戳和索引。但是,在步骤1)完成之前,不可能预测将在步骤2)中添加多少项,或者在步骤3)中将删除多少项,直到在算法的每个循环内完成步骤1)和2)。传入项的时间戳分布无法预测(新时间戳将在'未来'中除外),并且可能随时间变化 - 即可能存在一堆随机分布的时间戳,后面跟着一堆时间戳更大的时间戳(或小于)列表中剩余的任何项目。在任何时候都会有最大数量的元素等待处理,但这可能相当大~10 ^ 6-10 ^ 8,我需要尽快处理它们 - 请注意实际处理时间是相当小,所以对于大型数据集,我希望“调度”将主导我可以处理数据的速率。
如果我在步骤2)中将每个项目添加到链接的排序列表中,则步骤1)是O(0),但步骤2)是O(n)。如果我使用二叉树,那么步骤1)仍然是O(1),现在步骤2)最初是O(log n),但是如果时间戳没有很好地分布,那么树可能会非常快地变得不平衡,这将减慢步骤2)显着下降(如果我不经常重新平衡树,最终不会比O(n)好。)
我的猜测是,如果以正确的间隔进行重新平衡,那么具有定期重新平衡的二叉树的内容应该提供O(log n),但我认为这种问题很好 - 解决了,所以有人可以指导我一个合适的参考或给我一些建议,以帮助我避免重新发明轮子。
答案 0 :(得分:4)
使用数据结构堆,您可以使用O(logN)中的所有操作轻松完成此操作。
http://en.wikipedia.org/wiki/Heap_(data_structure)
堆将时间戳作为键。并且你需要一个额外的数组(或字典)来存储对Q =(item.Index,项目在堆中的位置)。
由于它是一堆,操作1)和2)将为每个项目花费O(logN)。
对于操作3),您需要从堆中删除随机项。幸运的是,正如所提到的那样here很容易。因为item.index不是它在堆中的实际位置,所以你需要上面提到的字典Q,通过它的item.Index在O(1)中寻找项目在堆中的位置(对于哈希映射) ,或者花费O(N)来寻找那个位置。并且由于项目的位置可能在操作期间(包括操作1和2)发生变化,因此请记住每次在堆中移动项目时更改Q中的值。
正如有人提到的优先级队列,我将在这里添加更多的单词。
优先级队列是一种抽象数据类型,带有一些抽象接口。这些界面不包括常识中的“删除随机项”。
堆是一种数据结构。
可以使用堆实现优先级队列。但是堆可以支持比优先级队列更多的操作。