以下是我所拥有的一些代码的摘录。
hpp:
class message_receiver
{
struct Chunk
{
// inits timestamp and other data memebers
Chunk();
boost::uint64_t m_timeStamp;
bool last;
std::vector<std::string> m_message;
...
};
struct Compare
{
bool operator()(const boost::shared_ptr<Chunk> p_left, const
boost::shared_ptr<Chunk> p_right) const
{
return p_left.m_timeStamp > p_right.m_timeStamp;
}
};
std::vector< boost::shared_ptr<Chunk> > m_chunks;
void setTimeStamp(const boost::shared_ptr<Chunk>& p_ca, bool isNew)
//other stuff
};
cpp:
void message_receiver::setTimeStamp(const boost::shared_ptr<Chunk>& p_ca, bool isNew)
{
p_ca->m_timeStamp = boost::chrono::duration_cast<boost::chrono::microseconds>(
boost::chrono::high_resolution_clock::now().time_since_epoch()).count();
if (isNew)
{
m_chunks.push_back(p_ca);
std::push_heap(m_chunks.begin(), m_chunks.end(), Compare());
}
else
{
std::make_heap(m_chunks.begin(), m_chunks.end(), Compare());
}
}
最终,设置时间戳是在循环中完成的。所以这个函数被多次调用,这应该保留所有时间戳以最小堆顺序
我希望将邮票保留在最小堆顺序中,以便在我的矢量前面可以获得最旧的时间戳。这是用std :: pop_heap完成的(未显示)。这是因为我需要顺序访问。
所以我的第一个问题是else语句中的std :: make heap调用。应该这样做吗?我搜索了一段时间的文档,除非使用std :: pop_heap或push heap,否则我没有看到任何其他方法来实际修改堆顺序,但在一种情况下我所做的就是更新对象。我假设当我这样做时,可能没有维护堆顺序?更新后是否有更好的方法来恢复堆属性?
其次,我意识到每次更新时间戳时,这段代码都会调用min-heapify,这是一种具有O(n)复杂度的算法。这对我的需求来说有点慢。我查看了使用boost Fibonacci堆,但经过一些研究后,似乎只有在缩小尺寸时效率更高,并且最终不能提供大的性能提升。经过大量研究后,我找不到能够有效满足我需求的容器,所以您是否知道其他任何可能在这里工作得更好的容器?
答案 0 :(得分:2)
我不相信堆是你最好的选择。
有几种自组织树具有你似乎追求的属性。
我建议使用这样的树(treap),然后重新插入被修改的元素。
问。 经过大量研究后,我找不到能够有效满足我需求的容器,所以您是否知道其他容器可能在这里工作得更好?
我会看看Boost Intrusive中的各种树容器。
Boost Intrusive在使用上有些奇特,但它看起来非常像你想要做的事情(因为Intrusive容器永远不会拥有它们包含的元素)。