STL学习——Priority_queue篇

STL学习——Priority_queue篇

  • 概述

    priority_queue是一个拥有权值观念的queue,它允许加入新元素,移除旧元素,审视元素值等功能。因为它是queue,故只允许底端加入元素,顶端取出元素。priorit_queue内元素并非依照被推入的次序排列,而是依照元素权值排列。权值最高者,排在最前面。

  • 实现

    priority_queue利用max_heap和vector表现的完全二叉树实现。它的实现完全以底部容器为根据,并使用heap处理规则,故实现简单。默认情况,使用vector为底部容器。由于它有“修改某物接口,形成另一风貌”性质,为适配器,被称为容器适配器。它不提供迭代器,也不提供遍历操作。其实现元素如下:

    // priority_queue类定义
    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 {
    ...
    public:
      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) {}
      // 以下用到的make_heap(),push_heap(),pop_heap()都是泛型算法
      // 注意,任一个构造函数都立刻位于底层容器内产生一个implicit represention heap
      priority_queue(const _Compare& __x, const _Sequence& __s) 
        : c(__s), comp(__x) 
        { make_heap(c.begin(), c.end(), comp); }
    
    #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 */
      // 判断priority_queue是否为空
      bool empty() const { return c.empty(); }
      // 返回priority_queue大小
      size_type size() const { return c.size(); }
      // 返回priority_queue队首元素
      const_reference top() const { return c.front(); }
      // priority入队操作
      void push(const value_type& __x) {
        __STL_TRY {
          // push_heap是泛型算法,先利用底层容器的push_back()将新元素推入末端,再重排heap。
          c.push_back(__x); 
          push_heap(c.begin(), c.end(), comp);   // push_heap是泛型算法
        }
        __STL_UNWIND(c.clear());
      }
      // priority_queue出队操作
      void pop() {
        __STL_TRY {
          // pop_heap是泛型算法,从heap内取出一个元素。他并不是真正将元素弹出,而是重排heap,然后在以底层容器的pop_heap()取得被弹出的元素
          pop_heap(c.begin(), c.end(), comp);
          c.pop_back();
        }
        __STL_UNWIND(c.clear());
      }
    };
    ...
    
  • 参考文献

    STL源码剖析——侯捷

    STL源码

你可能感兴趣的:(Queue,heap,STL,Priority)