• SGI STL优先队列priority_queue


    priority_queue简介

    跟普通queue不同的是,priority_queue拥有权值的概念,允许加入新元素、移除旧元素、查看元素值等。priority_queue本身也是一个queue,因此只允许在尾部加入元素,头部取出元素,除此外无法从别的位置存取元素。

    普通queue是按先进先出的规则取出元素,内部存储顺序也是按进入先后顺序排列;priority_queue并非如此排列,而是自动按元素的权值排列。权值最高值,排在最前面。

    默认情况,priority_queue用一个max-heap实现,而priority_queue是以vector作为底部容器表现的complete binary tree(完全二叉树)。因为max-heap可以满足priority_queue所需的“依赖权值高低自动排序”的特性。

    priority_queue数据结构

    类似于stack、queue,priority_queue也是以底部容器完成操作的,加上heap处理规则。因此,STL中priority_queue往往不被归类为container(容器),而被归类为container adapter(容器适配器)。

    #   define __STL_DEPENDENT_DEFAULT_TMPL(_Tp) = _Tp
    
    // 优先队列
    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) {}
    
      // 以下任意构造函数都立刻于底层容器内产生一个implicit representation heap
      // 因为调用了make_heap
      priority_queue(const _Compare& __x, const _Sequence& __s)
        : c(__s), comp(__x)
        { make_heap(c.begin(), c.end(), comp); }
    
      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);
      }
    
      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 {
          // push_heap 是泛型算法, 先利用底层容器的push_back()将新元素
          // 推入末端, 再重排heap
          c.push_back(__x);
          push_heap(c.begin(), c.end(), comp); // 泛型算法
        }
        __STL_UNWIND(c.clear()); // commit or clear all
      }
      void pop() {
        __STL_TRY {
          // pop_heap 是泛型算法, 从heap内取出一个元素. 不是真正将元素弹出, 而是重排heap,
          // 然后再以底层容器的pop_back() 取得被弹出的元素.
          pop_heap(c.begin(), c.end(), comp);
          c.pop_back();
        }
        __STL_UNWIND(c.clear()); // commit or clear all
      }
    };
    
    #   define __STL_TRY try
    #   define __STL_CATCH_ALL catch(...)
    #   define __STL_THROW(x) throw x
    #   define __STL_RETHROW throw
    #   define __STL_NOTHROW throw()
    #   define __STL_UNWIND(action) catch(...) { action; throw; }
    

    priority_queue测试实例

    #include <queue>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    int main()
    {
           { // test case1: test priority_queue
                  int ia[9] = { 0,1,2,3,4,8,9,3,5 };
                  priority_queue<int> ipq{ ia, ia + 9 };
                  cout << "size = " << ipq.size() << endl; // size = 9
                  for (size_t i = 0; i < ipq.size(); i++) {
                         cout << ipq.top() << ' '; // 9 9 9 9 9 9 9 9 9
                  }
                  cout << endl;
                  while (!ipq.empty()) {
                         cout << ipq.top() << ' '; // 9 8 5 4 3 3 2 1 0
                         ipq.pop();
                  }
                  cout << endl;
           }
           return 0;
    }
    
  • 相关阅读:
    P1273 有线电视网
    P2015 二叉苹果树
    POJ 3659 Cell Phone Network
    POJ 1463 Strategic game
    NC51178 没有上司的舞会
    NC15033 小G有一个大树
    13. SpringBoot 日志框架的默认配置 和 指定日志文件 以及 ProFile 功能
    12. SpringBoot 日志框架的关系 研究中间包的替换
    11. SpringBoot 日志框架 — 解决和思路
    41.el和template区别 & VUE实现分离写法
  • 原文地址:https://www.cnblogs.com/fortunely/p/16249169.html
Copyright © 2020-2023  润新知