C++ 包含指向对象指针的STL堆

C++ 包含指向对象指针的STL堆,c++,data-structures,stl,C++,Data Structures,Stl,我有一个std::list objectList容器,我需要在以下场景中对其进行排序和维护: 每个对象都有一个提供成本的特定字段(例如浮动值)。该成本值用于比较两个对象,就像它们是浮点数一样 集合必须有序(升序),并且必须快速找到新插入元素的正确位置 可以删除最低的要素(就成本而言),也可以更新几个任意定位要素的成本。然后必须尽可能快地对列表重新排序,利用其已排序的性质 我可以使用任何其他stl容器/机制来考虑这三个行为属性吗?它非常类似于一个堆,我认为使用make_heap可以很好地对列表

我有一个
std::list objectList
容器,我需要在以下场景中对其进行排序和维护:

  • 每个对象都有一个提供成本的特定字段(例如浮动值)。该成本值用于比较两个对象,就像它们是浮点数一样
  • 集合必须有序(升序),并且必须快速找到新插入元素的正确位置
  • 可以删除最低的要素(就成本而言),也可以更新几个任意定位要素的成本。然后必须尽可能快地对列表重新排序,利用其已排序的性质
我可以使用任何其他stl容器/机制来考虑这三个行为属性吗?它非常类似于一个堆,我认为使用
make_heap
可以很好地对列表进行排序。我需要一个指针容器,因为还有其他几个数据结构依赖于这些指针

那么,我如何选择一个更好的容器,它也是指针友好的,并且允许通过查看指向类型的比较运算符进行排序

澄清:我需要一个最适合场景的stl容器,并且可以成功地包装指针或引用。(例如,我简要地读到,
std::set
容器可能是一个很好的候选者,但我没有使用它的经验)

基于以下答案的当前实施:

struct SHafleEdgeComparatorFunctor
    {
        bool operator()(SHEEdge* lhs, SHEEdge* rhs)
        {
            return (*lhs) < rhs;
        }
    };

std::multiset<SHEEdge*, SHafleEdgeComparatorFunctor>    m_edges;

我会开始使用一个智能指针比如
shared_ptr
而不是原始指针(原始指针很好,例如,如果它们正在观察指针,比如作为函数参数传递的指针,但是当您具有所有权语义时,比如在本例中,最好使用智能指针)

然后,我将以
std::vector
作为容器开始

所以,试着让它成为
vector

您可以将其性能与
列表
进行比较

(还要注意,
std::list
std::vector
有更多的开销,因为它是一个基于节点的容器,每个节点都有一些开销;相反,
std::vector
分配一个连续的内存块来存储它的数据,在这种情况下,
shared_ptr
s;因此
std::vector
也更为重要。)“缓存友好”等)


一般来说,
std::vector
提供了非常好的性能,是“首选”容器的良好选择。在任何情况下,您的里程数可能非常高,最好是测量性能(速度)为了更好地了解您的具体情况。

如果我正确理解了您的要求,您正在寻找正确的容器来使用

实际上,
std::set
似乎是您想要做的事情的正确容器,但它将取决于所有用例

  • 您是否需要具有O(1)访问元素的权限
  • 所使用的操作成本最重要的是什么
std::set
使用键对元素进行排序,并且不允许有重复项(如果需要重复项,请查看
std::multiset
)。添加元素时,它将自动插入到正确的位置。通常,您不希望使用原始指针作为键,因为对象可以为空

另一种选择是使用
std::vector>
,正如@MikePro所说,将指针放在智能指针中是一种很好的做法,以避免手动删除它们(例如,在发生异常时避免任何内存泄漏)。如果使用向量,则必须使用
std::sort
std::find
等函数出现在
标题或
std::vector::insert

通常,此图像有助于找到您的容器。它并不完美(因为您必须知道比显示内容更多的内容),但它通常能很好地完成其工作:


我确实会使用
std::set
。在您的需求中,最棘手的一点是更新现有的元素

std::set
始终是排序的。您必须使用有用的比较运算符将指针包装在类中,或者必须向集合传递比较谓词

然后,您将自动获得排序属性,并获得最低元素的固定时间删除

您还可以更新日志复杂性中的成本值:只需从集合中删除对象并重新添加它。这将与排序容器的速度一样快


插入和删除在一个集合中都很快。

对我来说,听起来你已经回答了自己的问题:堆似乎是解决问题的完美结构。@NPE:我想问题会变成:“有没有STL(或Boost)容器类似于堆?“…@NPE:ty,我编辑了这个问题并添加了这个案例的澄清。看看。这是如何回答的?它会使用MyObject操作符吗?@Alon:您可以使用
std::sort()
std::vector
进行排序,并传递lambda来实现特定的自定义排序逻辑。指针也是一样:)但使用共享的\u ptr始终是一个可靠的建议使用
std::sort()有任何保证吗
在一个向量容器上,它的大部分元素都已经向比较器排序了w.r.t.,它的效率将与教科书堆数据结构一样高吗?(我不确定它是否重新排序向量)@ TeoDron:我只写一些代码和测量速度:有几个因素起作用,比如<代码> STD::vector 当有足够的容量与基于节点的容器开销时,在插入项目时更有效率,所以我认为你应该考虑整个行为,不仅仅是一些单一的方面。我现在切换到<代码> SET,但是我将考虑和温和地按照MikePro的建议/答案来测试向量版本。感谢+1的支持
bool operator<(SHEEdge* rhs) 
    {
        return this->GetCollapseError() < rhs->GetCollapseError();
    }