时间戳组织的容器

时间:2015-10-09 20:29:11

标签: c++ algorithm boost heap

以下是我所拥有的一些代码的摘录。

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堆,但经过一些研究后,似乎只有在缩小尺寸时效率更高,并且最终不能提供大的性能提升。经过大量研究后,我找不到能够有效满足我需求的容器,所以您是否知道其他任何可能在这里工作得更好的容器?

1 个答案:

答案 0 :(得分:2)

我不相信堆是你最好的选择。

有几种自组织树具有你似乎追求的属性。

我建议使用这样的树(treap),然后重新插入被修改的元素。

  

问。 经过大量研究后,我找不到能够有效满足我需求的容器,所以您是否知道其他容器可能在这里工作得更好?

我会看看Boost Intrusive中的各种树容器。

Boost Intrusive在使用上有些奇特,但它看起来非常像你想要做的事情(因为Intrusive容器永远不会拥有它们包含的元素)。