STL中包括三种队列:queue、deque和priority_queue。
其中,priority_queue实际上不是队列,而是堆结构。下面主要介绍queue和deque的创建和使用方法。
queue为STL的适配容器,具有队列的结构特性。其创建方法与stack类似。操作除了将top函数改为front函数,并添加获取队尾函数back外,其他与stack类似
#include
using namespace std;
typedef int datatype;
#include
#include
#includeint main()
{queuequ; //创建queue对象,底层容器为dequequeue>qu1; //创建queue对象,底层容器为vectorqueue>qu2; //创建queue对象,底层容器为listqu.push(3); qu.push(5); qu.push(2); //入队cout << qu.size() << endl; //队中元素个数cout << qu.back() << endl; while (!qu.empty()) { //判断队列是否为空cout << qu.front() << " "; //获取队头元素qu.pop(); //出队}cout << endl;
}
deque为STL提供的标准容器之一,成为双端队列,为适配器容器stack和queue的默认底层容器。deque和vector非常类似,均属于线性的随机容器,且都是采用动态数组来存放元素。
所有vector对象的创建和初始化方法都适用于创建和初始化deque对象:
dequedq; //创建一个空的deque对象
dequedq2(12, 5); //创建一个含有12个元素的deque对象,元素的初始值为5
int a[] = { 1,4,7,2,5,8,3,6,9 };
dequedq4(a + 2, a + 6); //创建还有4个元素的deque对象,元素的初始值为a[2]~a[5]
对vector对象的操作大多数都适用于deque对象,除了与容量相关的函数(如capacity()、reserve()等)。另外,deque对象还有一些特有的操作,主要是可以对队头进行操作:
dq.push_front(7);
dq.pop_front();
其他操作与vector完全一样。
一般来说,只有具有先进先出特征的算法都可以利用队列实现。在计算机操作系统中经常会出现多个用户或任务同时请求同一资源的情形,如果按照先申请先处理的策略(如果任务有优先级,则要采用优先队列),则可以用队列来存放待处理的资源请求序列。例如,当在某一时间段多次向打印机提交打印请求时,由于一次只能打印一个文件,因此利用队列保存由用户提交的打印作业,实现先申请先打印。
利用队列可以很好地实现异步处理数据传送和存储,例如,当频繁向数据库中插入数据时,可以将插人指令按照申请插入的时间顺序存放到队列中,然后依次执行插入指令。另外,可以将较慢的处理逻辑和有并发数量限制的处理逻辑,通过消息队列放在后台处理,如发送电子邮件等。
后面许多算法的实现也是采用队列,如广度优先搜索、拓扑排序等。下面介绍队列的一些简单应用。
【例1】在周末舞会上,男士和女士在进入舞厅后分别按性别排成一队。一首舞曲为一轮,在每一轮开始时,依次将男队和女队处于队头的两人配成舞伴,并出队,直到其中一队已全部配对。如果男女人数不同,则人数较多的那一队中未配对者继续排队等待下一轮。当一轮跳完后,参加这一轮跳舞的所有人按照原先的顺序排在男队或女队的后面。假设共进行n轮,编写模拟算法,输出每一轮的舞伴配对情况。
例如,如果参加舞会的男士为{"张一","杨帆”,"李华",赵勇"},女士为{"李丽”,“孙茜”,”刘倩”},则前三轮配对情况如下:
第1轮的配对情況:(张一 李丽),(杨帆 孙茜),(李华 刘倩);
第2轮的配对情况:(赵勇 李丽),(张一 孙茜),(杨帆 刘倩)
第3轮的配对情况:(李华 李丽) (赵勇 孙茜) (张一 刘倩)
#include
using namespace std;
typedef int datatype;
#include
#include
#includevoid partnerMatching(vectorm, vectorf, int n)
{int i = 0, j = 0, msz = m.size(), fsz = f.size();queuemq, fq;for (int i = 0; i < msz; i++) mq.push(m[i]); //初始化男队队列for (int i = 0; i < fsz; i++) fq.push(f[i]); //初始化女队队列for (int i = 1; i <= n; i++) {cout << "第" << i << "轮的配对情况:" << endl;j = min(msz, fsz); //满足其中人数少的一队全部配对为一轮while (j--) {string tmp;tmp = mq.front(), mq.pop(), mq.push(tmp); //男队出队,出队后加入队尾cout << tmp << " ";tmp = fq.front(), fq.pop(), fq.push(tmp); //女队出队,出队后加入队尾cout << tmp << endl;}}
}int main()
{vectorm = { "张毅","杨帆","李华","赵勇" };vectorf = { "李丽","孙茜","刘倩" };partnerMatching(m, f, 7);
}
单调队列是指队列元素严格单调的队列。如果队列的元素按从队头到队尾的顺序为严格单调递增,则称为递增队列;如果队列的元素按从队列到队尾的顺序为严格单调递减,则称为递减队列。
单调队列是对队列的入队和出队操作加了一些限制条件,以保证队列的单调性,且队头和队尾都可以进行出队操作,而入队操作只能在队尾,取元素只能在队头。
由于单调队列需要从队列的两端出队,因此通常用双端队列deque实现。
单调队列一般用于解决某个范围内的最小值或最大值问题,另一个典型应用是对一些动态规划进行优化。
【例1】利用单调队列求数组在固定长度区间的最大值。举例子:数组a={2,5,3,4,10,6,3,7,8},设置滑动窗口为3,求滑动窗口范围内的最大值,结果={5,5,10,10,10,7,8}。
#include
using namespace std;
typedef int datatype;
#include
#includevoid rangeMax(vectorve, int m) {dequedq;for (int i = 0; i < ve.size(); i++) {while (!dq.empty() && ve[dq.back()] < ve[i]) //去尾dq.pop_back();dq.push_back(i); //下标入队,控制滑动窗口的长度if (i >= m - 1) {if (!dq.empty() && i - dq.front() >= m) //掐头,大于滑动窗口范围,去除第一个dq.pop_front();cout << ve[dq.front()] << " "; //输出队头}}
}int main()
{vectorve = { 2,5,3,4,10,6,3,7,8 };rangeMax(ve, 3);
}
下一篇:C和C++大全