当我搞砸时,简单的问题 cppreference并更改pop_heap
std::vector<int> v { 60 , 20 , 50 , 10 , 5 , 30 , 45 };
std::make_heap(v.begin(), v.end());
std::cout << "v: ";
for (auto i : v) std::cout << i << ' ';
std::cout << '\n';
std::pop_heap(v.begin(), v.end()); // moves the largest to the end
The result is:
v: 60 20 50 10 5 30 45
after pop_heap: 50 20 45 10 5 30 60
CPP参考告诉我
std :: pop_heap - 首先将位置中的值和位置last-1中的值进行切换,并使子范围[first,last-1]成为最大堆。这具有从范围[first,last]定义的堆中移除第一个(最大)元素的效果。
我知道我错过了一些东西,因为如果我读了第一个和最后一个将被交换。我知道,在完成所有操作之后,pop_heap将消除60但是该命令最终会如何结束。我认为我的理解不在于last-1,但我无法确定
答案 0 :(得分:1)
在std::pop_heap
中,您将first
指定为v.begin()
,它返回指向第一个元素的迭代器,last
作为v.end()
,根据{{ 3}}“返回一个迭代器,引用向量容器中的past-the-end元素。”这意味着last-1
实际上是向量中的最后一个元素。因此,交换的元素是第一个(60
)和最后一个(45
)。之后是子范围[first
,last-1
),意味着所有内容但最后一个元素(现在是60
)再次变为heap
,这意味着第一个元素是最大的(50
)。
因此,对于订单,您可以确定向量中的第一个元素是50
,最后一个元素是60
。至于其余的,cplusplus.com状态在笔记中:
最大堆是一系列具有以下属性的元素[f,l]:
- * f是范围
中的最大元素- 可以使用std :: push_heap()
添加新元素- 可以使用std :: pop_heap()
删除第一个元素元素的实际安排是实现定义的。
所以剩下的就是方便实现这些方法的方法。
答案 1 :(得分:0)
就像它说的那样,将first
与last - 1
交换,然后执行std::make_heap(first, last - 1)
注意:first
和last
是std::pop_heap
的2个参数,分别是v.begin()
和v.end()
。这意味着它会在您的示例中交换v.begin()
和v.end() - 1
。
请参阅此example