简介

这个头文件定义了两个跟队列有关的类----quque、priority_queue,分别实现的是队列优先队列这两个概念。 但是与这两个类模版与其它类模版(vector、array等)最大的不同是,它们是 容器适配器

容器适配器

顾名思义,容器适配器是对容器的适配,从代码层面来讲,它就是对容器的再封装。 因此,这些容器适配器实际上都是由其他容器的功能实现的。 不难看出, 容器适配器所具有的功能是内部容器功能的子集

普通的类封装一般是为了封装成特定问题领域下的类,提供特定的接口,以解决开发中遇到的实际问题为主要目的; 而作为一门语言库中的库类,它们更多考虑的是可重用性,所以库类一般封装成像stack、quque等具有抽象性的概念。

队列

你可以把队列看成一种被适配的容器,它有两个重要的特性:

  • FIFO(first-in first-out): 先入队的元素总是先出队。
  • 两端出入: 元素从一端入队,从另一端出队。

操作对应的成员函数

  • 入队 -> push
  • 出队 -> pop

为什么少了很多常见函数

细心的你们肯定发现了,queue类模版提供的函数很少,一些非常常见的函数都没有。 如果让我用一句话来解释的话,那就是----所有涉及头尾两端外的位置的函数,都不在队列的概念内!

因为在队列中,所有元素的存取都只能通过入队和出队操作。 如果你想获取位于中间位置的元素,那么对不起,你只能先把前面的元素取出来;如果你想对队中的元素本身进行操作,抱歉,你得先获取它(当然,然,出于实际上的方便使用,queue类模版还是包含了一些本不在概念内的函数:size、back等)。 在队列上的操作是非常有限的,所以队列只在一些特殊且适合情况下才被使用。

那这些消失的函数都包括哪些呢?

  1. 所有Iterator函数: 没错,是所有,你没有看错! 因为所有迭代器都可以通过步进(advance函数或者算数加减)操作,从而指向队列中间的元素。
  2. 更改大小的非pop非push函数(包括增加和删除): 队列大小的改变只能被入队出队操作影响。
  3. 所有随机存取函数 : 元素的获取只能按序,而获取是操作的前提。

优先队列

优先队列也是一中容器适配器,这种队列主要具有以下两个性质:

  • 按优先级排序
  • 按优先级获取

在优先队列中,所有的元素都是按照优先级排序。 具体来说,当每一次元素入队时,都会对队列进行优先级排序,优先级最高的排在最前面,优先级最低的排在最后面。 而获取元素时,只能按优先级从高到底依次获取。

从某种意义上来说,队列(queue)和 优先队列(priority_queue)是相似的,甚至可以说 队列是优先队列的特殊情况。 它们都按照某种规律排序,只是排序的规则不同: 队列按元素的入队时间排序,优先队列按元素优先级排序。

优先级

那么如何定义该种队列的优先级呢? 在声明优先队列对象的时候,你可以传递一个二元谓词(Binary Predicate)来执行排序的任务。 如果你不传递自定义的二元谓词,则优先队列默认使用functional头文件中的less函数对象。

这个二元谓词执行严格弱序排序(Strick Weak Ordering)。这个排序有以下四个属性(假设comp为比较操作,x、y、z为待比较的元素, x non-comp y等价于(x comp y) == false && (x comp y) == false)):

  • 自反性((x comp x) == false)
  • 不对称性((x comp y) != (y comp x))
  • 传递性(((x comp y) == true, (y comp z) == true)) => ((x comp z) == true)))
  • 不可比性((x non-comp y, y non-comp z) => (x non-comp z))

这着实有点晦涩,搞得我都头晕了。 简单的讲,这个二元谓词比较两个元素,如果第一个比较的元素应该排在第二个前面(即第一个元素的优先级高于第二个),那么它返回true。 元素的相等性也是通过这个谓词操作推出来的:如果第一个元素的优先级不高于第二个元素,并且第二个元素的优先级也不高于第一个元素,那么这两个元素就相等。

操作对应的函数

  • 入队 -> push
  • 出队 -> pop

值得注意的是,不像队列那样,优先队列里的元素没有时间前后之分,所以priority_queue模版类去掉了front和back成员函数,代之以top函数,用以指代下一个出队的优先级最高的元素。

C++ 头文件系列(queue)的更多相关文章

  1. C++ 头文件系列(array)

    注意,该头文件仅在C++11中标准才开始出现. 简介 与语言内置的数组一样, array类模版支持几乎所有内置数组包含的特性: 顺序的(sequence) 内存连续的(contiguous stora ...

  2. C++ 头文件系列(stack)

    简介 该头文件只含有一个类模版stack, 它实现栈的概念,是一个容器适配器(说实话,在写这篇随笔之前我都不知道有这么个类模版). 栈 栈只有一个重要的特性: LIFO(last-in first-o ...

  3. C++ 头文件系列(vector)

    简介 vector头文件包含vector的类模版以及该模版的显示特化版本vector< bool >. vector是C++容器库中非常通用的一种容器,如果你不知道该决定使用哪一种容器,或 ...

  4. C++ 头文件系列(map)

    简介 该头文件包含两个概念相似的容器----map.multimap. 而这两个容器反映的概念就是 映射. 这两个容器 相同 的属性有: 关联性 映射 动态增长 键(Key)唯一性 这两个不相同的属性 ...

  5. C++ 头文件系列(unordered_map、unordered_set)

    简介 很明显,这两个头文件分别是map.set头文件对应的unordered版本. 所以它们有一个重要的性质就是: 乱序 如何乱序 这个unorder暗示着,这两个头文件中类的底层实现----Hash ...

  6. C++ 头文件系列(iterator)

    简介 该头文件围绕迭代器展开,定义了一系列与迭代器有关的概念,但最最最重要的一点就是----它和其它容器一起实现了C++容器的Iterator设计模式. Iterators are a general ...

  7. C++ 头文件系列 (algorithm)

    简介 algorithm头文件是C++的标准算法库,它主要应用在容器上. 因为所有的算法都是通过迭代器进行操作的,所以算法的运算实际上是和具体的数据结构相分离的 ,也就是说,具有低耦合性. 因此,任何 ...

  8. C++ 头文件系列 (bitset)

    简介 该头文件有关位集,实际上是vector 位 位本质上对应bool的概念,只有0或1,true或false两种对立的值. 但很可惜,字节才是机器上最小的存储单元,所以bool基本上是由一个字节大小 ...

  9. C++ 头文件系列(iosfwd)

    简介 输入输出历来都是语言的重要部分,在C++中,该库也是占据了相当大的一部分. C++的输入输出库是其遵循面向对象设计的结果,并结合了泛型编程. 以下是这些库类的关系图(箭头标示继承,白框表示摸板, ...

随机推荐

  1. Fluent Validation

    .NET业务实体类验证组件Fluent Validation   认识Fluent Vaidation. 看到NopCommerce项目中用到这个组建是如此的简单,将数据验证从业务实体类中分离出来,真 ...

  2. 探秘IntelliJ IDEA 13中的版本控制——Subversion 1.8

    IntelliJ IDEA 中引入的重要特性就是版本控制,而在IntelliJ IDEA 13中的体现便是支持最新的Subversion 1.8. 相对于之前版本对Subversion的支持,Subv ...

  3. JQUERY 插件开发——MENU(导航菜单)

    JQUERY 插件开发——MENU(导航菜单) 故事背景:由于最近太忙了,已经很久没有写jquery插件开发系列了.但是凭着自己对这方面的爱好,我还是抽了一些时间来过一下插件瘾的.今天的主题是导航菜单 ...

  4. oracle读写文件--利用utl_file包对磁盘文件的读写操作

    oracle读写文件--利用utl_file包对磁盘文件的读写操作 摘要: 用户提出一个需求,即ORACLE中的一个表存储了照片信息,字段类型为BLOB,要求能导出成文件形式. 本想写个C#程序来做, ...

  5. ref引用类型,数组型参数,out输出参数

    ref和out的相同点和不同点 共同点:都是引用传递不同点:ref的参数在调用之前一定要赋值,在方法调用的过程中可以不要赋值.    out的参数在调用之前可以不赋值,在方法调用的过程中一定要赋值. ...

  6. MVC如何在Pipeline中接管请求的?

    MVC如何在Pipeline中接管请求的? 文章内容 上个章节我们讲到了,可以在HttpModules初始化之前动态添加Route的方式来自定义自己的HttpHandler,最终接管请求的,那MVC是 ...

  7. Effective C++(19) 设计class犹如设计type

    问题聚焦:     这一节不涉及代码,但是我们需要明确的一点是,思想比代码要重要得多.     设计优秀的classes是一项艰巨的工作,就像设计好的types一样.     我们应该带着和“语言设计 ...

  8. WCF Restful Service的服务

    构建基于WCF Restful Service的服务 前言 传统的Asmx服务,由于遵循SOAP协议,所以返回内容以xml方式组织.并且客户端需要添加服务端引用才能使用(虽然看到网络上已经提供了这方面 ...

  9. 领域驱动设计(DDD)的实际应用

    领域驱动设计(DDD)的实际应用   笔者先前参与了一个有关汽车信息的网站开发,用于显示不同品牌的汽车的信息,包括车型,发动机型号,车身尺寸和汽车报价等信息.在建模时,我们只需要创建名为Car的实体( ...

  10. 图解Javascript之字符串

    好东西分享给大家,但要尊重事实!!!因此特别说明:本图非我本人亲自所作,乃我大天朝网友所绘制.个人感觉此图,覆盖全面,细节考虑甚周全,因此分享给大家,同时在此特别感谢网友的无私分享!