SGISTL源码探究-优先级队列

前言

在上一小节中,我们分析了heap算法,其实是为了priority_queue优先级队列做准备,它也不是容器,而是配接器,因为它是通过vector来实现的,然后封装了一些vector提供的接口供自己使用而形成的。
优先级队列,即一种特殊的队列,但是它内部的元素没有按照传统队列的先进先出这种顺序排序,而是按照元素的权值进行排列,所以执行出队操作时,出队的是权值最大的元素。

priority_queue

在SGISTL的实现中,priority_queue队列底部实现的容器就是vector,然后再配合heap提供的一些算法就可以完成优先级队列的所有功能了。
它的实现源码如下:

定义部分
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template <class T, class Sequence = vector<T>,
          class Compare = less<typename Sequence::value_type> >
#else
template <class T, class Sequence, class Compare>
#endif
class  priority_queue {
public:
  //定义的一些常用的类型
  typedef typename Sequence::value_type value_type;
  typedef typename Sequence::size_type size_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) {}

#ifdef __STL_MEMBER_TEMPLATES
  //以迭代器范围构造时,调用make_heap函数使这些元素形成堆结构
  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)
    : c(first, last) { make_heap(c.begin(), c.end(), comp); }
#else /* __STL_MEMBER_TEMPLATES */
  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)
    : c(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(); }
  /* 将元素压入优先级队列
   * 先将元素压入vector尾部
   * 然后调用push_heap进行调整
   */
  void push(const value_type& x) {
    __STL_TRY {
      c.push_back(x);
      push_heap(c.begin(), c.end(), comp);
    }
    __STL_UNWIND(c.clear());
  }
  /* 调用pop_heap将权值最大的元素存在vector尾部
   * 接着调用vector提供的pop_back弹出尾部元素
   */
  void pop() {
    __STL_TRY {
      pop_heap(c.begin(), c.end(), comp);
      c.pop_back();
    }
    __STL_UNWIND(c.clear());
  }
};
例子
#include <iostream>
#include <queue>
using namespace std;
int main()
{
    vector<int> vec{0, 1, 2, 3, 4, 5, 6};
    priority_queue<int> pri_que(vec.begin(), vec.end());


    while(!pri_que.empty())
    {
        cout << pri_que.top() << endl;
        pri_que.pop();
    }

    pri_que.push(10);
    cout << pri_que.top() << endl;

    return 0;
}

很简单的一个例子,这里为了方便理解,就只使用了最普通的int作为权值,你可以尝试声明一个对象,然后定义自己的compare类作为大小比较标准,然后在创建priority_queue的时候指定比较标准。

小结

在本小节中,我们分析了priority_queue的实现,其实它的实现很简单,在我们并没有深入源码的时候可能觉得它很复杂,但是并不是。
priority_queue主要借用了vector作为底部容器,以及使用了heap有关的算法,只是改变了相应的接口,就形成了另外一种数据结构,不得不感叹stl的精妙。
关于序列式容器,我们就告一段落,接下来我们将进入到关联式容器。但是由于setmap这类关联式容器都借助了红黑树实现,所以我们要先对红黑树做个了解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 最新的SGI STL源码可以从以下几个渠道进行下载。 首先,你可以在GitHub上找到SGI STL的官方仓库。在该仓库,你可以浏览并下载最新的源代码文件。GitHub提供了多种形式的下载选项,你可以选择下载整个仓库的压缩文件(zip格式),或者直接克隆仓库到本地。 其次,你还可以访问SGI STL的官方网站,该网站上提供了SGI STL的下载链接。进入官方网站后,你可以查看可供下载的最新版本,然后选择所需的版本进行下载。官方网站通常会提供详细的文档和说明,帮助你更好地使用和理解SGI STL源码。 此外,你还可以通过搜索引擎查找其他第三方网站或平台上提供的SGI STL源码下载链接。这些网站也可能提供最新版本的下载选项,但请注意检查源码的可靠性和合法性。 无论你选择哪种方式下载SGI STL源码,建议先仔细阅读相关文档,理解源码的结构和使用方法,以便更好地应用和扩展SGI STL库。 ### 回答2: 最新的SGI STL源码可以通过以下方式进行下载: 1. 访问SGI官方网站:SGI(STL)是由Silicon Graphics Inc.开发的,可以在其官方网站上找到最新的源码下载链接。可以使用搜索引擎来查找SGI官方网站,并在网站上查找STL源码的下载链接。 2. 在Github上搜索:Github是一个开源代码托管平台,许多开发者会将他们的代码上传到这个平台上。在Github上,你可以搜索SGI STL,并找到与STL相关的仓库。浏览相关仓库,找到最新版本的STL源码并进行下载。 3. 使用相关的开发者论坛和社区:在许多专门的开发者论坛和社区,你可以找到你所需要的开发资源。参与这些论坛,提出你的需求,寻求帮助并询问最新的SGI STL源码下载途径。其他开发者可能会分享他们的经验和提供相应的下载链接。 4. 前往开发者相关的网站:有一些开发者网站会提供各种开发资源的链接和下载。搜索一些开发者网站,并检查他们所提供的STL源码下载选项。 总之,要下载最新的SGI STL源码,你可以通过访问SGI官方网站、使用Github进行搜索、参与开发者论坛和社区或前往开发者相关的网站来获取下载链接。确保你下载的是经过验证的可靠源码,并在你的项目合理使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值