【问题标题】:INVALID HEAP when using STL make_heap / push_heap / pop_heap使用 STL make_heap / push_heap / pop_heap 时的无效堆
【发布时间】:2012-01-09 04:52:34
【问题描述】:

我已经为 std::make_heap / push_heap / pop_heap 编写了简单的包装器:

template <typename T, typename Cont = std::vector<T>, typename Compare = std::less<typename Cont::value_type> >  
class Heap  
{  
public:  
    inline void init() { std::make_heap(m_data.begin(), m_data.end(), Compare()); }  
    inline void push(const T & elm) { m_data.push_back(elm); std::push_heap(m_data.begin(), m_data.end(), Compare()); }  
    inline const T & top() const { return m_data.front(); }  
    inline void pop() { std::pop_heap(m_data.begin(), m_data.end(), Compare()); m_data.pop_back(); }  

private:  
    Cont m_data;  
};  

我使用的是这样的:

class DeliveryComparator
{
public:
    bool operator()(Delivery * lhs, Delivery * rhs)
    {
        if(lhs->producer != rhs->producer) return *lhs->producer < *rhs->producer;  
        if(lhs->rate == rhs->rate) return lhs->diff < rhs->diff;  
        return lhs->rate < rhs->rate; 
    }
};

Heap<Delivery*, std::vector<Delivery*>, DeliveryComparator> packages; 

但有时我会收到 INVALID HEAP 标准调试消息。 我只是通过适当的堆方法使用堆。当消息发生时,m_data 不为空。

堆有什么问题?

*我用的是MSVS2010

【问题讨论】:

  • 为什么不使用std::priority_queue
  • std::priority_queue 不是已经是堆函数的封装了吗?
  • 你的比较器中是否有一些额外的*,即*lhs-&gt;producer,应该只是lhs-&gt;producer
  • @KennyTM 和Kerrek:哦,我完全忘记了priority_queue,谢谢。无论如何,我的堆有问题吗?
  • @DarrenEngwirda 那些星星是必要的,生产者是指针类型,我不想比较地址,而是在生产者实例中调用 operator

标签: c++ stl heap


【解决方案1】:

编辑堆的数据后(待添加的除外),堆被销毁。如果你接下来使用 push_heap() 方法,这个异常将被抛出。您应该使用 make_heap() 而不是 push_heap()。例如(顺便说一句,以下示例是我程序中的代码 sn-p):

if (highHeap[0] < solvedQuestions){ 
               lowHeap[lenghOfLowHeap++] = highHeap[0]; // *It only add a new item without destroy the heap 
               highHeap[0] = solvedQuestions;
               // Update the Heap
               push_heap(lowHeap, lowHeap + lenghOfLowHeap); 
               //push_heap(highHeap, highHeap + lenghOfHighHeap, greater<int>()); // invalid heap exception. Because the heap was destroyed by "highHeap[0] = solvedQuestions;"
               make_heap(highHeap, highHeap + lenghOfHighHeap, greater<int>());
           }

【讨论】:

  • "可以通过调用函数make_heap将一个范围变成一个堆。创建后,可以通过分别使用push_heap和pop_heap在其中添加和删除值来保留其堆属性。" - 来自push_heap
猜你喜欢
  • 2020-11-07
  • 2011-02-18
  • 2015-09-01
  • 2014-12-17
  • 1970-01-01
  • 1970-01-01
  • 2012-10-22
  • 1970-01-01
  • 2015-06-30
相关资源
最近更新 更多