将对象推入向量然后将向量推入堆中时无效的堆

时间:2015-07-20 23:03:04

标签: c++ sorting vector heap

我正在尝试使用class Bar来存储Foo的有序数组,由其成员var提供,如下所示。

我期待这个输出像3,4,5,但我得到5,3,4

我正在使用我自己的比较功能(强制因为我的Foo struct有更多数据),在推回向量后,我将向量推回堆并重新排序。

我在这里缺少什么?

我想要的是将Foo对象推入队列,并自动重新排序。

struct Foo
{
    int var;
    //etc.
};

struct compare
{
   bool operator()(const Foo& s1, const Foo& s2)
   {
       return s1.var < s2.var;
   }
};

class Bar
{
private:
    std::vector<Foo> m_vector;
public:
    Bar() 
    {
        std::make_heap(m_vector.begin(), m_vector.end(), compare());
    }

    ~Bar() {}

    void push (const Foo& t)
    {
        m_vector.push_back(t);
        std::push_heap(m_vector.begin(),m_vector.end(), Comp());
    }

    void pop()
    {
        m_vector.pop_back();
    }

    void dump(void)
    {
        printf ("\n Dumping:");
        for(int i = 0; i < m_vector.size() ; i++)
        {
            printf ("%d ", m_vector.at(i).var);
        }
        printf ("\n");
    }
};

int main() 
{
    Bar myBar;

    myBar.dump();

    Foo t1;
    t1.var = 3;

    myBar.push(t1); 
    myBar.dump();

    Foo t2;
    t2.var = 4;

    myBar.push(t2); 
    myBar.dump();

    Foo t3;
    t3.var = 5;

    myBar.push(t3); 
    myBar.dump();

    return 0;
}

1 个答案:

答案 0 :(得分:2)

如果以相反的顺序获取对象,则应切换比较信号:

bool operator()(const Foo& s1, const Foo& s2)
{
   return s1.var > s2.var;
}

然而,似乎你没有正确理解堆。堆不保留已排序的对象,而是仅部分排序。请注意,它们仍将按顺序弹出对象,但您需要实际弹出它们,只需迭代堆就不会这样做。

请注意,下图中的数组根本没有排序。但是,当渲染为树时,堆确实拥有一个重要的属性:每个节点都小于其所有后代。这就是部分排序的意思。对象没有排序,但它们以一种可以有效排序的方式相互关联。

enter image description here

要让你的元素重新排序,你需要弹出它们。

编辑:顺便说一下,您应该使用std::pop_heap,而不是std::vector::pop_back。由于在前面的解释之后应该清楚的原因