zoukankan      html  css  js  c++  java
  • 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 容器,用户也可以自己指定容器的类型。
  • 相关阅读:
    nodejs初期,搭建一个登陆注册功能,(原生的)
    关于vue如何创建一个自定义组件(这是项目中经常得用的)
    关于vue 使用watch方法,详解。
    怎样用Nodejs搭建一个服务器
    关于Promise的理解及运用
    Ado.NET SQLHelper(2)
    Ado.NET SQLHelper
    MS SQLSERVER 自增ID列竟然会重复
    SQL中Left Join 与Right Join 与 Inner Join 与 Full Join的区别
    thread.start和threadstart.invoke的区别
  • 原文地址:https://www.cnblogs.com/xiaojianliu/p/12602998.html
Copyright © 2011-2022 走看看