推送,弹出和基本堆

时间:2016-08-05 04:56:13

标签: c++

当我搞砸时,简单的问题 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,但我无法确定

2 个答案:

答案 0 :(得分:1)

std::pop_heap中,您将first指定为v.begin(),它返回指向第一个元素的迭代器,last作为v.end(),根据{{ 3}}“返回一个迭代器,引用向量容器中的past-the-end元素。”这意味着last-1实际上是向量中的最后一个元素。因此,交换的元素是第一个(60)和最后一个(45)。之后是子范围[firstlast-1),意味着所有内容但最后一个元素(现在是60)再次变为heap,这意味着第一个元素是最大的(50)。

因此,对于订单,您可以确定向量中的第一个元素是50,最后一个元素是60。至于其余的,cplusplus.com状态在笔记中:

  

最大堆是一系列具有以下属性的元素[f,l]:

     
      
  • * f是范围
  • 中的最大元素   
  • 可以使用std :: push_heap()
  • 添加新元素   
  • 可以使用std :: pop_heap()
  • 删除第一个元素   
     

元素的实际安排是实现定义的。

所以剩下的就是方便实现这些方法的方法。

答案 1 :(得分:0)

就像它说的那样,将firstlast - 1交换,然后执行std::make_heap(first, last - 1)

之类的操作

注意:firstlaststd::pop_heap的2个参数,分别是v.begin()v.end()。这意味着它会在您的示例中交换v.begin()v.end() - 1

请参阅此example