priority_queue

priority_queue

//@ 优先队列,默认底层容器是 vector,利用 max-heap 规则 
template <class _Tp, 
          class _Sequence __STL_DEPENDENT_DEFAULT_TMPL(vector<_Tp>),
          class _Compare
          __STL_DEPENDENT_DEFAULT_TMPL(less<typename _Sequence::value_type>) >
class priority_queue {
  // requirements:
  __STL_CLASS_REQUIRES(_Tp, _Assignable);
  __STL_CLASS_REQUIRES(_Sequence, _Sequence);
  __STL_CLASS_REQUIRES(_Sequence, _RandomAccessContainer);
  typedef typename _Sequence::value_type _Sequence_value_type;
  __STL_CLASS_REQUIRES_SAME_TYPE(_Tp, _Sequence_value_type);
  __STL_CLASS_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp);

public:
 //@ priority_queue仅支持对头部和尾部的操作,
 //@ 所以不定义STL要求的 pointer, iterator, difference_type 
  typedef typename _Sequence::value_type      value_type;
  typedef typename _Sequence::size_type       size_type;
  typedef          _Sequence                  container_type;

  typedef typename _Sequence::reference       reference;
  typedef typename _Sequence::const_reference const_reference;
protected:
  _Sequence c;  //@ 底层容器
  _Compare comp; //@ 元素大小比较标准
public:
  priority_queue() : c() {}
  explicit priority_queue(const _Compare& __x) :  c(), comp(__x) {}
  priority_queue(const _Compare& __x, const _Sequence& __s) 
    : c(__s), comp(__x) 
    { make_heap(c.begin(), c.end(), comp); } //@ 构造函数实现,将底层容器具有 heap 特性
    
//@ priority_queue 有几种构造函数形式
#ifdef __STL_MEMBER_TEMPLATES
  template <class _InputIterator>
  priority_queue(_InputIterator __first, _InputIterator __last) 
    : c(__first, __last) { make_heap(c.begin(), c.end(), comp); }

  template <class _InputIterator>
  priority_queue(_InputIterator __first, 
                 _InputIterator __last, const _Compare& __x)
    : c(__first, __last), comp(__x) 
    { make_heap(c.begin(), c.end(), comp); }

  template <class _InputIterator>
  priority_queue(_InputIterator __first, _InputIterator __last,
                 const _Compare& __x, const _Sequence& __s)
  : c(__s), comp(__x)
  { 
    c.insert(c.end(), __first, __last);
    make_heap(c.begin(), c.end(), comp);
  }

#else /* __STL_MEMBER_TEMPLATES */
  priority_queue(const value_type* __first, const value_type* __last) 
    : c(__first, __last) { make_heap(c.begin(), c.end(), comp); }

  priority_queue(const value_type* __first, const value_type* __last, 
                 const _Compare& __x) 
    : c(__first, __last), comp(__x)
    { make_heap(c.begin(), c.end(), comp); }

  priority_queue(const value_type* __first, const value_type* __last, 
                 const _Compare& __x, const _Sequence& __c)
    : c(__c), comp(__x) 
  { 
    c.insert(c.end(), __first, __last);
    make_heap(c.begin(), c.end(), comp);
  }
#endif /* __STL_MEMBER_TEMPLATES */
  
};

常用操作

  bool empty() const { return c.empty(); }
  size_type size() const { return c.size(); }
  const_reference top() const { return c.front(); } //@ 获得头部元素
  void push(const value_type& __x) {
    __STL_TRY {
      c.push_back(__x);  //@ 先向底层容器尾部插入元素
      push_heap(c.begin(), c.end(), comp); // 重排 heap
    }
    __STL_UNWIND(c.clear());
  }
  void pop() {
    __STL_TRY {
      pop_heap(c.begin(), c.end(), comp); //@ 先调用 pop_heap,将最大值放到底层容器的尾部
      c.pop_back(); //@ 然后从底层容器弹出
    }
    __STL_UNWIND(c.clear()); 
  }

总结

  • priority_queue 是拥有优先级的 queue,不过容器内的元素并不是根据加入顺序排列,而是根据用户定义的优先级进行排列,默认是大顶堆。
  • priority_queue 只能在队列尾部加入元素,在头部取出元素。不能遍历容器,因此不需要自己设置迭代器。
  • priority_queue 是基于某种容器作为底部结构的,默认容器是 vector 容器,用户也可以自己指定容器的类型。
原文地址:https://www.cnblogs.com/xiaojianliu/p/12602998.html