繁体   English   中英

删除max并添加新元素时,单个“ Heapify”调用c ++ std :: make_heap

[英]Single 'Heapify' call when removing max and adding a new element c++ std::make_heap

是否可以弹出最大值,推送一个新元素,然后调用push_heap,维护堆,并且仅调用一次bubble down算法?

    // What I think is correct:
    heap.push_back(new_element);
    std::push_heap(heap.begin(), heap.end());
    std::pop_heap(heap.begin(), heap.end());
    heap.pop_back();

    // What I hope is correct:
    heap.pop_back();        
    heap.push_back(new_element);
    std::push_heap(heap.begin(), heap.end());

删除最大值并将新元素推送到堆是否“安全”? 我已经测试过了,情况似乎确实如此。 我有理由不这样做吗?

非常相关的问题: 如何在C ++标准库中更改堆中的max元素?

在通过make_heap创建的最大堆中,最大元素将位于最前面,而删除它的适当方法是使用std::pop_heap ,period。

一个pop_front (不是像您所假定的pop_back )确实会从堆中删除最大的元素,但是不再保证您拥有堆。 也就是说,弹出第一个元素会有效地将子堆移到根中。 如果合适的子项更大,则将丢失heap属性(即使它适用于第一组子项,由于数组的移位,它可能会使任何子树无效)。

另外,如果您使用的是类似std::vector的连续容器,那么pop_front (在vector::begin上调用std::vector::erase )会不幸地浪费您O(N)的时间,这很多比pop_heap的O(log N)复杂度pop_heap

您可能(过早)进行优化的一种情况是,如果您只是想将最大元素与另一个与现有最大元素大小一样大的元素交换 ,或者如果失败,则大于等于最大元素的最大子元素。 在那种情况下,您可能会达到O(1)复杂度,但是在一般情况下这不太可能。

最好只有两个O(log N)操作。 函数的增长如此缓慢,以至于1000和100万个元素堆之间几乎没有差异。

您所要求的几乎是帖子正文中链接问题的完全重复。

// Precondition is that v is already a heap.
int get_max_element_add_new (std::vector<int> &v, int value) {
    v.push_back(value);
    std::pop_heap(v.begin(), v.end());
    value = v.back();
    v.pop_back();
    return value;
}

由于pop_heap将交换第一个和最后一个值,因此back将包含您要删除的最大值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM