推送、弹出和基本堆

push, pop, and basic heap

本文关键字:推送      更新时间:2023-10-16

当我乱搞时提出的简单问题CPP 首选项并更改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::p op_heap-交换位置中的值和位置 last-1 中的值,并使子范围 [first, last-1( 成为最大堆。这具有从范围 [first, last] 定义的堆中删除第一个(最大(元素的效果。

我知道我错过了一些东西,因为如果我阅读第一个和最后一个会被交换。我知道在一切都说完并完成之后,pop_heap将消除 60,但订单最终如何以它的方式结束。我认为我不明白的是最后 1 个,但我不能确定

std::pop_heap中,您将first指定为 v.begin() ,这将返回一个指向第一个元素的迭代器,last作为v.end(),根据 cplusplus.com"返回引用向量容器中过去结束元素的迭代器。这意味着last-1实际上是向量中的最后一个元素。所以交换的元素是第一个(60(和最后一个(45(。之后子范围 [firstlast-1 (,意味着除了最后一个元素(现在60(之外的所有元素再次被制成heap,这意味着第一个元素是最大的(50(。

因此,对于顺序,保证向量中的第一个元素是50,最后一个元素是60 。至于其余的,cpppreferences在注释中指出:

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

  • *f 是该系列中最大的元素
  • 可以使用 std::p ush_heap(( 添加新元素
  • 第一个元素可以使用 std::p op_heap(( 删除

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

因此,其余的只是以一种方便实现方法的方式排列。

就像它说的,first换成last - 1然后做类似std::make_heap(first, last - 1)

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

请参阅此示例