C++ 头文件系列(queue)
简介
这个头文件定义了两个跟队列有关的类----quque、priority_queue,分别实现的是队列 和 优先队列这两个概念。 但是与这两个类模版与其它类模版(vector、array等)最大的不同是,它们是 容器适配器。
容器适配器
顾名思义,容器适配器是对容器的适配,从代码层面来讲,它就是对容器的再封装。 因此,这些容器适配器实际上都是由其他容器的功能实现的。 不难看出, 容器适配器所具有的功能是内部容器功能的子集。
普通的类封装一般是为了封装成特定问题领域下的类,提供特定的接口,以解决开发中遇到的实际问题为主要目的; 而作为一门语言库中的库类,它们更多考虑的是可重用性,所以库类一般封装成像stack、quque等具有抽象性的概念。
队列
你可以把队列看成一种被适配的容器,它有两个重要的特性:
- FIFO(first-in first-out): 先入队的元素总是先出队。
- 两端出入: 元素从一端入队,从另一端出队。

操作对应的成员函数
- 入队 -> push
- 出队 -> pop
为什么少了很多常见函数
细心的你们肯定发现了,queue类模版提供的函数很少,一些非常常见的函数都没有。 如果让我用一句话来解释的话,那就是----所有涉及头尾两端外的位置的函数,都不在队列的概念内!
因为在队列中,所有元素的存取都只能通过入队和出队操作。 如果你想获取位于中间位置的元素,那么对不起,你只能先把前面的元素取出来;如果你想对队中的元素本身进行操作,抱歉,你得先获取它(当然,然,出于实际上的方便使用,queue类模版还是包含了一些本不在概念内的函数:size、back等)。 在队列上的操作是非常有限的,所以队列只在一些特殊且适合情况下才被使用。
那这些消失的函数都包括哪些呢?
- 所有Iterator函数: 没错,是所有,你没有看错! 因为所有迭代器都可以通过步进(advance函数或者算数加减)操作,从而指向队列中间的元素。
- 更改大小的非pop非push函数(包括增加和删除): 队列大小的改变只能被入队出队操作影响。
- 所有随机存取函数 : 元素的获取只能按序,而获取是操作的前提。
优先队列
优先队列也是一中容器适配器,这种队列主要具有以下两个性质:
- 按优先级排序
- 按优先级获取

在优先队列中,所有的元素都是按照优先级排序。 具体来说,当每一次元素入队时,都会对队列进行优先级排序,优先级最高的排在最前面,优先级最低的排在最后面。 而获取元素时,只能按优先级从高到底依次获取。
从某种意义上来说,队列(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)的更多相关文章
- C++ 头文件系列(array)
注意,该头文件仅在C++11中标准才开始出现. 简介 与语言内置的数组一样, array类模版支持几乎所有内置数组包含的特性: 顺序的(sequence) 内存连续的(contiguous stora ...
- C++ 头文件系列(stack)
简介 该头文件只含有一个类模版stack, 它实现栈的概念,是一个容器适配器(说实话,在写这篇随笔之前我都不知道有这么个类模版). 栈 栈只有一个重要的特性: LIFO(last-in first-o ...
- C++ 头文件系列(vector)
简介 vector头文件包含vector的类模版以及该模版的显示特化版本vector< bool >. vector是C++容器库中非常通用的一种容器,如果你不知道该决定使用哪一种容器,或 ...
- C++ 头文件系列(map)
简介 该头文件包含两个概念相似的容器----map.multimap. 而这两个容器反映的概念就是 映射. 这两个容器 相同 的属性有: 关联性 映射 动态增长 键(Key)唯一性 这两个不相同的属性 ...
- C++ 头文件系列(unordered_map、unordered_set)
简介 很明显,这两个头文件分别是map.set头文件对应的unordered版本. 所以它们有一个重要的性质就是: 乱序 如何乱序 这个unorder暗示着,这两个头文件中类的底层实现----Hash ...
- C++ 头文件系列(iterator)
简介 该头文件围绕迭代器展开,定义了一系列与迭代器有关的概念,但最最最重要的一点就是----它和其它容器一起实现了C++容器的Iterator设计模式. Iterators are a general ...
- C++ 头文件系列 (algorithm)
简介 algorithm头文件是C++的标准算法库,它主要应用在容器上. 因为所有的算法都是通过迭代器进行操作的,所以算法的运算实际上是和具体的数据结构相分离的 ,也就是说,具有低耦合性. 因此,任何 ...
- C++ 头文件系列 (bitset)
简介 该头文件有关位集,实际上是vector 位 位本质上对应bool的概念,只有0或1,true或false两种对立的值. 但很可惜,字节才是机器上最小的存储单元,所以bool基本上是由一个字节大小 ...
- C++ 头文件系列(iosfwd)
简介 输入输出历来都是语言的重要部分,在C++中,该库也是占据了相当大的一部分. C++的输入输出库是其遵循面向对象设计的结果,并结合了泛型编程. 以下是这些库类的关系图(箭头标示继承,白框表示摸板, ...
随机推荐
- SQL点滴33—SQL中的字符串操作
原文:SQL点滴33-SQL中的字符串操作 计算字符串长度len()用来计算字符串的长度 select sname ,len(sname) from student 字符串转换为大.小写lower() ...
- DDD分层架构之聚合
DDD分层架构之聚合 前面已经介绍了DDD分层架构的实体和值对象,本文将介绍聚合以及与其高度相关的并发主题. 我在之前已经说过,初学者第一步需要将业务逻辑尽量放到实体或值对象中,给实体“充血”,这样可 ...
- NHibernate中使用memcache二级缓存
在NHibernate中使用memcache二级缓存 一.Windows下安装Memcache 1. 下载 http://jehiah.cz/projects/memcached-win32/ ...
- 点击按钮,通过JS代码实现复制INPUT表单,表格:
获取表单: <SCRIPT LANGUAGE="JavaScript"> function copyinput() { var input=document.getEl ...
- 如何在在网页上显示pdf文档
------解决方案--------------------通过flash插件 ------解决方案--------------------RAD PDF Release 2.7 http://www ...
- foreach,foreachelse
foreach,foreachelse Table of Contents目录 iteration 用于显示当前循环的执行次数[待考] first : 当前 foreach 循环第一次执行时 firs ...
- MVC 5 的 EF6 Code First 入门 系列:排序、筛选和分页
这是微软官方SignalR 2.0教程Getting Started with Entity Framework 6 Code First using MVC 5 系列的翻译,这里是第三篇:排序.筛选 ...
- Object Pool
设计模式之美:Object Pool(对象池) 索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):实现 DatabaseConnectionPool 类. 意图 运用对象池化 ...
- SQLServer数据库误删数据找回
记一次SQLServer数据库误删数据找回 昨天 同事在本机清理数据库表时,连接到了生产机,误删了二十几张表,幸好是晚上加班的时候删除的,生产机上当时是一天一备份,还原备份是最后的策略,最关键的还是要 ...
- DIP And DI
依赖倒置(DIP)与依赖注入(DI) 依赖倒置原则(Dependency Inversion Principle)为我们提供了降低模块间耦合度的一种思路,依赖注入(Dependency Injec ...