【问题标题】:Random access priority queue随机访问优先级队列
【发布时间】:2010-12-12 17:32:08
【问题描述】:

继续List to priority queue

我正在使用随机访问实现改进的 priority_queue。

template <class T, class Container = std::vector<T> >
class Heap {
public:
    Heap() {}

    Heap(const Container& container) {
        container_ = container;
        std::make_heap(container_.begin(), container_.end());
    }

    Heap<T, Container>& operator=(const Heap<T, Container>& heap) {
        if (this != &heap)
            container_ = heap.container_;

        return *this;
    }

    void push(const T& x) {
        container_.push_back(x);
        std::push_heap(container_.begin(), container_.end());
    }

    void pop() {
        std::pop_heap(container_.begin(), container_.end());
        container_.pop_back();
    }

    const T& top() {
        return container_.front();
    }

    const Container& getContainer() const {
        return container_;
    }

    T& operator[](size_t n) {
        return container_[n];
    }

    typename Container::const_iterator begin() const {
        return container_.begin();
    }

    typename Container::const_iterator end() const {
        return container_.end();
    }

    size_t size() const {
        return container_.size();
    }

    T& base() {
        return container_.back();
    }

    Container::iterator erase(Container::iterator position) {
        return container_.erase(position);
    }

private:
    Container container_;
};

我走对了吗?

  • 修复了一元构造函数。
  • 改进的代码。

【问题讨论】:

  • 如果是随机访问,就不再是优先队列了。
  • 它应该表现得像一个priority_queue,但可以随机访问。

标签: c++ priority-queue random-access


【解决方案1】:

我觉得不太好:

  • 一元构造函数应通过 const 引用获取参数。
  • 赋值运算符不检查自赋值。
  • getContainer() 方法显示接口不够清晰 - 为什么您要像这样简单地公开实现细节?
  • 最重要的是:为什么需要“随机访问优先级队列”?

【讨论】:

  • 我已经修复了一元构造函数。我不明白你的第二个陈述,我要修正第三点。关于你的问题,这是一个大学项目,如你所见,结构很糟糕。
  • 感谢伟大的链接。我更新了我的代码。好点吗?很抱歉给您带来不便,但这是我第一次做这样的事情。
  • 希望这样做的一个可能原因是遍历队列的元素(即查看更多内容)。我总是觉得std::stack&lt;&gt; 特别痛苦,因为它不允许你检查它的内容。我总是切换回直接使用底层向量。
【解决方案2】:

您的 pop() 方法可能违反堆排序。使用 pop_heap() 而不是 pop_back()。我现在似乎找不到任何其他错误。

您可以通过推入一个随机整数并一个一个地 pop() 来轻松测试这样的实现。您应该按排序顺序将它们取回。这称为堆排序。

建议:

  • 您可以为此类实现一个 const 迭代器,而不是将 ref 返回到容器。

  • 请注意,您不应更改随机访问元素的键,因为它可能会破坏堆结构。如果您需要这样的功能,您应该实现一个 change_key 函数,它可以安全地更改密钥并维护堆排序。

【讨论】:

  • @Renato:您的 begin()end() 方法返回 Container::iterator。他们应该总是返回Container::const_iterator 或者有人可以(阅读:)搞砸你的堆。
  • @André:谢谢!我改变了方法。还有什么需要改进的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-04
  • 2011-12-20
  • 2011-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-13
相关资源
最近更新 更多