【问题标题】:Why priority queue is implemented using heaps when we can implement it using just vector more efficiently当我们可以更有效地使用向量来实现优先级队列时,为什么使用堆来实现它
【发布时间】:2018-05-03 10:19:50
【问题描述】:

为什么priority_queue 使用堆实现而不使用堆我们也可以只使用向量来实现它。

假设我们使用向量作为队列并保持元素按降序排列。 我们可以将其用作优先队列。

对于插入:我们可以使用二分查找。 Complexity O(logN)

对于删除:这里我们也可以使用二分查找。 Complexity O(logN)

对于顶部元素:O(1)

此外,我们可以在O(1) 时间内访问第 k 个最大元素,而堆则不然。

那么,我们为什么要使用堆来实现优先级队列呢?

【问题讨论】:

  • 二分搜索如何插入任何东西?
  • 哦!我忘记的那件事
  • 这里似乎没有必要投反对票。
  • StackOverflow 的 just posted 一篇关于该网站似乎不太受欢迎的博客文章。人们对这个问题的回答就像一个例子。 @prashantshishodia:很抱歉你遇到了这种情况。

标签: c++ stl priority-queue implementation


【解决方案1】:

对于插入:我们可以使用二分查找。复杂度 O(logN)

对于删除:这里我们也可以使用二分查找。复杂度 O(logN)

不,你不能。通过使用排序数组/向量,您只能在 O(log N) 上搜索正确的索引,但要进行实际插入或删除,您必须移动其他元素,即 O(N)

【讨论】:

  • 哦!明白了,我的错
【解决方案2】:

默认优先级队列使用 std::vector。它将堆算法分层,以获得所需的性能特征。

草图实现:

template <typename T>
class priority_queue
{
    std::vector<T> elems;
public:
    std::vector<T>::const_reference top() const { 
         return elems.front(); // O(1)
    }
    void push( const T& value ) { 
         elems.push_back(value); // Amortized O(1)
         std::push_heap(elems.begin(), elems.end()); // O(logN)
    }
    void pop() {
         std::pop_heap(elems.begin(), elems.end());  // O(logN)
         elems.pop_back(); // O(1)
    }
}

比较你的建议

template <typename T>
class priority_queue
{
    std::vector<T> elems;
public:
    std::vector<T>::const_reference top() const { 
         return elems.back(); // O(1)
    }
    void push( const T& value ) { 
         std::vector<T>::iterator pos = std::lower_bound(elems.begin(), elems.end(), std::greater<>{}); // O(logN)
         elems.insert(pos, value); // O(N)
    }
    void pop() {
         elems.pop_back(); // O(1)
    }
}

【讨论】:

  • top() 实际上应该返回 elems.front()
  • 我引用的是第一个 sn-p,而不是第二个。你实际上是pop_back(),但是你pop的元素实际上是pop_heap之前向量的front()处的元素,因为pop_heap首先交换了front()back(),然后移动旧的back() 在向量中的正确位置。
猜你喜欢
  • 2011-06-09
  • 2013-11-30
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多