当前位置: 首页 > 知识库问答 >
问题:

使用'std::更大'通过'priority_queue'创建最小堆的原因

简俊楚
2023-03-14

我想知道为什么使用priority_queue创建min堆时,应该使用std::more

std::priority_queue<T, std::vector<T>, std::greater<T> > min_heap;

对我来说,因为最小的值总是位于堆的顶部,所以使用的类应该是std::less

更新:另一方面,由于priority\u queue(max heap)的默认行为是在顶部保留最大值,因此在我看来,std::greater应该用于最大堆创建,而不是最小堆创建

共有3个答案

南门正业
2023-03-14

看见http://en.cppreference.com/w/cpp/container/priority_queue.优先级队列设计用于将最大值置于顶部。如果使用默认的std::less比较器,就会发生这种情况。因此,如果需要反向行为,则需要使用反向比较器,std::greater

相德宇
2023-03-14

C堆函数make_heappush_heappop_heap在最大堆上运行,这意味着使用默认比较器时,顶部元素是最大值。因此,要创建最小堆,需要使用greater

我怀疑使用最大堆而不是最小堆是因为使用less操作更容易实现。在C语言中,less有特权成为所有STL算法的“默认”比较器;如果您只打算实现一个比较操作(而不是=),那么它应该是

此外,某些算法,如nth\u元素需要最大堆。

越鸿才
2023-03-14

逻辑论点如下

  1. std::priority_queue是一个容器适配器;对于序列容器(如std::vector),基本内存考虑使背面成为修改的首选位置(使用pop_back()push_back()
  2. priority\u queue原语基于std::make\u heap(构造函数),std::pop\u heapcontainer::pop\u backpriority\u queue::pop)和container::push\u backpriority\u queue::push
  3. pop_heap将占用底层存储的前面,并将其放在后面,然后恢复堆不变量。与之相反的是push\u heap
  4. max\u heap上执行sort\u heap(最大值最初位于前面)将重复从前到后弹出,并根据less对范围进行排序(这是默认的比较运算符)
  5. 因此,max_heap的首选实现是将max元素w.r.t.less放在前端,通过priority_queue::top(底层container::front)访问
  6. 我们仍然可以争论,带有std::less比较器的priority\u队列表示max\u堆是否直观。它可以通过反转比较器的参数来定义为min_heap(但请参见@T.C.的评论,对于C 98绑定,这相当冗长),在对各种堆函数的调用中无处不在。一个(对我来说)违反直觉的结果是top()不会给元素赋予最高优先级
 类似资料:
  • 我一直想知道为什么STL优先级队列默认使用最大堆而不是最小堆。我想到的两个明显的用例是寻路(Dijkstra)和构建霍夫曼代码。这两种算法都需要首先拉取最小元素。由于排序(std::sort)默认使用升序,我想知道priority_queue背后的设计原因是什么,因为我非常喜欢默认的最小堆。

  • 为什么 首先返回最大的元素(即是最大优先级队列),即使它使用 作为比较类型? 当我想创建一个最小队列时,这尤其让我感到困惑,这将由 是您的最大值。如果您使用创建优先级队列,那么前面是最小的值。我意识到优先级队列使用堆,但我觉得这是有充分理由的。

  • 对于堆排序,如果我们想按升序对数组排序,那么应该在最大堆还是最小堆中转换堆?

  • 问题内容: 如何通过环境变量设置Java的最小和最大堆大小? 我知道可以在启动Java时设置堆大小,但是我希望通过服务器上的环境变量对此进行调整。 问题答案: 您不能直接使用环境变量来做到这一点。您需要使用传递给java命令的“非标准”选项集。运行:java -X了解详细信息。您要查找的选项是-Xmx和- Xms(这是“初始”堆大小,因此可能是您要查找的内容。) 诸如Ant或Tomcat之类的某些

  • 问题内容: 我想用Java创建一个Stack,但是要固定大小。例如,创建一个新的堆栈,将大小设置为10,然后在将项目推入堆栈时将其填满,并在将其填满到十时将堆栈中的最后一个项目推出(移出)。我想使用Stack,因为它使用LIFO,非常适合我的需求。 但是Stack从Vector继承的setSize()方法似乎并没有真正限制Stack的大小。我想我缺少有关堆栈如何工作的信息,或者堆栈并不是要受到约束

  • 对于我的节点应用程序,我有一个运行在Debian上的服务器(app.js),它使用socket.io向我的客户机(index.html)提供html和websocket数据。我正在尝试制作一个回合制的HTML5多人游戏。 在使用socket.emit()/io.emit()和socket.on()成功执行了多次数据传输后,我的服务器在socket.emit()调用上崩溃,出现错误 “events.