C++ STL make_heap 和 pop_heap 不工作

发布于 2024-09-01 12:41:51 字数 1282 浏览 6 评论 0 原文

我需要使用堆,所以我搜索了STL,但它似乎不起作用,我写了一些代码来解释我的意思:

#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>

struct data
{
    int indice;
    int tamanho;
};


bool comparator2(const data* a, const data* b)
{
    return (a->tamanho < b->tamanho);
}

int main()
{

        std::vector<data*> mesas;

        data x1, x2, x3, x4, x5;

        x1.indice = 1;
        x1.tamanho = 3;

        x2.indice = 2;
        x2.tamanho = 5;

        x3.indice = 3;
        x3.tamanho = 2;

        x4.indice = 4;
        x4.tamanho = 6;

        x5.indice = 5;
        x5.tamanho = 4;

        mesas.push_back(&x1);

        mesas.push_back(&x2);

        mesas.push_back(&x3);

        mesas.push_back(&x4);

        mesas.push_back(&x5);


        make_heap(mesas.begin(), mesas.end(), comparator2);

        for(int i = 0 ; i < 5 ; i++)
        {
            data* mesa = mesas.front();
            pop_heap(mesas.begin(),mesas.end());
            mesas.pop_back();

            printf("%d, %d\n", mesa->indice, mesa->tamanho);
        }

    return 0;
};

这就是我得到的:

4, 6
2, 5
1, 3
3, 2
5, 4

所以它不能作为堆工作,因为向量上的最大元素没有正确返回。

或者我做错了什么?

I need to use a Heap, so i've searched about the STL one, but it doesn't seem to work, i wrote some code to explain what i mean:

#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>

struct data
{
    int indice;
    int tamanho;
};


bool comparator2(const data* a, const data* b)
{
    return (a->tamanho < b->tamanho);
}

int main()
{

        std::vector<data*> mesas;

        data x1, x2, x3, x4, x5;

        x1.indice = 1;
        x1.tamanho = 3;

        x2.indice = 2;
        x2.tamanho = 5;

        x3.indice = 3;
        x3.tamanho = 2;

        x4.indice = 4;
        x4.tamanho = 6;

        x5.indice = 5;
        x5.tamanho = 4;

        mesas.push_back(&x1);

        mesas.push_back(&x2);

        mesas.push_back(&x3);

        mesas.push_back(&x4);

        mesas.push_back(&x5);


        make_heap(mesas.begin(), mesas.end(), comparator2);

        for(int i = 0 ; i < 5 ; i++)
        {
            data* mesa = mesas.front();
            pop_heap(mesas.begin(),mesas.end());
            mesas.pop_back();

            printf("%d, %d\n", mesa->indice, mesa->tamanho);
        }

    return 0;
};

and this is what i get:

4, 6
2, 5
1, 3
3, 2
5, 4

So it's not working as a heap, as the maximum element on the vector is not being returned right.

Or am i doing something wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

养猫人 2024-09-08 12:41:51

您需要将 comparator2 传递给 std::pop_heap,因为这就是您创建堆的方式。否则,它将使用指针的默认小于运算符,该运算符仅比较指针值。

You need to pass comparator2 to std::pop_heap since that is how you created the heap. Otherwise, it will use the default less than operator for pointers, which simply compares the pointer values.

等数载,海棠开 2024-09-08 12:41:51

MSN的回答是正确的。但是,以下任一样式指南都可以防止此错误:

  • 声明比较器适用于引用,而不是对象,如操作符<那样。使用对象的向量,而不是指针。

    bool comparator2(const data& a, const data& b)
    {
        返回(a.tamanho < b.tamanho);
    }
    

    您可能确实需要指针向量,在这种情况下,这不适用。

  • 使用std::priority_queue(来自),它将pop_heappop_back联系在一起为了你,记住你的比较器。这需要一个函子比较器:

    struct comparator2 { bool operator()(const data& a, const data& b)
    {
        返回(a.tamanho < b.tamanho);
    } };
     
    std::priority_queue<数据,向量<数据>,比较器2>台面;
     // 或 std::priority_queue, comparator2>;
    台面.推(x1);
    
  • 最优雅的方法是使其成为数据的默认比较:

    结构数据
    {
        int 指数;
        国际塔马尼奥;
         
        friend bool 运算符<(const data& a, const data& b)
        {
            返回(a.tamanho < b.tamanho);
        }
    };
    std::priority_queue<数据>;台面;
    台面.推(x1);
    

priority_queue 还可以采用预填充的未排序容器,并将复制该容器。

MSN's answer is correct. However, either of a couple style guidelines can prevent this error:

  • Declare the comparator to work on references, not objects, as operator< would. Use a vector of objects, not pointers.

    bool comparator2(const data& a, const data& b)
    {
        return (a.tamanho < b.tamanho);
    }
    

    You might really need the vector of pointers, in which case this doesn't apply.

  • Use std::priority_queue (from <queue>), which ties together pop_heap and pop_back for you, remembering your comparator. This requires a functor comparator:

    struct comparator2 { bool operator()(const data& a, const data& b)
    {
        return (a.tamanho < b.tamanho);
    } };
     
    std::priority_queue<data, vector<data>, comparator2> mesas;
     // or std::priority_queue<data, vector<data>, comparator2>
    mesas.push(x1);
    
  • Most elegant way is to make this the default comparison for data:

    struct data
    {
        int indice;
        int tamanho;
         
        friend bool operator<(const data& a, const data& b)
        {
            return (a.tamanho < b.tamanho);
        }
    };
    std::priority_queue<data> mesas;
    mesas.push(x1);
    

priority_queue can also take a prefilled unsorted container, which it will copy.

提笔落墨 2024-09-08 12:41:51

std::set 怎么样

#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
#include <set>

struct data
{
    // Always put constructors on.
    // When the constructor is finished the object is ready to be used.
    data(int i,int t)
        :indice(i)
        ,tamanho(t)
    {}

    int indice;
    int tamanho;

    // Add the comparator to the class.
    // Then you know where to look for it.
    bool operator<(data const& b) const
    {
        return (tamanho < b.tamanho);
    }
};



int main()
{

        std::set<data> mesas;

        // Dont declare all your variables on the same line.
        // One per line otherwise it is hard to read.
        data x1(1,3);
        data x2(2,5);
        data x3(3,2);
        data x4(4,6);
        data x5(5,4);

        mesas.insert(x1);
        mesas.insert(x2);
        mesas.insert(x3);
        mesas.insert(x4);
        mesas.insert(x5);
        // You don't actually need the variables.
        // You could have done it in place.
        mesas.insert(data(6,100));

        // Use iterator to loop over containers.
        for(std::set<data>::iterator loop = mesas.begin(); loop != mesas.end(); ++loop)
        {
            printf("%d, %d\n", loop->indice, loop->tamanho);
        }

    return 0;
};

What about std::set

#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
#include <set>

struct data
{
    // Always put constructors on.
    // When the constructor is finished the object is ready to be used.
    data(int i,int t)
        :indice(i)
        ,tamanho(t)
    {}

    int indice;
    int tamanho;

    // Add the comparator to the class.
    // Then you know where to look for it.
    bool operator<(data const& b) const
    {
        return (tamanho < b.tamanho);
    }
};



int main()
{

        std::set<data> mesas;

        // Dont declare all your variables on the same line.
        // One per line otherwise it is hard to read.
        data x1(1,3);
        data x2(2,5);
        data x3(3,2);
        data x4(4,6);
        data x5(5,4);

        mesas.insert(x1);
        mesas.insert(x2);
        mesas.insert(x3);
        mesas.insert(x4);
        mesas.insert(x5);
        // You don't actually need the variables.
        // You could have done it in place.
        mesas.insert(data(6,100));

        // Use iterator to loop over containers.
        for(std::set<data>::iterator loop = mesas.begin(); loop != mesas.end(); ++loop)
        {
            printf("%d, %d\n", loop->indice, loop->tamanho);
        }

    return 0;
};
她如夕阳 2024-09-08 12:41:51

我有一个类似的问题,并且能够用这样的方法解决它:

struct comparator2 { bool operator()(data const * const a, data const * const b)
{
    return (a->tamanho < b->tamanho);
 } };

std::priority_queue<data*, std::vector<data*>, comparator2> mesas;

I had a similar problem and was able to solve it with something like this:

struct comparator2 { bool operator()(data const * const a, data const * const b)
{
    return (a->tamanho < b->tamanho);
 } };

std::priority_queue<data*, std::vector<data*>, comparator2> mesas;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文