含义
(deque,全名double-ended queue)是一种具有队列和栈的性质的数据结构。双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行。
双端队列是限定插入和删除操作在表的两端进行的线性表。这两端分别称做端点1和端点2。也可像栈一样,可以用一个铁道转轨网络来比喻双端队列。在实际使用中,还可以有输出受限的双端队列(即一个端点允许插入和删除,另一个端点只允许插入的双端队列)和输入受限的双端队列(即一个端点允许插入和删除,另一个端点只允许删除的双端队列)。而如果限定双端队列从某个端点插入的元素只能从该端点删除,则该双端队列就蜕变为两个栈底相邻的栈了。
STL
deque的实现比较复杂,内部会维护一个map(注意!不是STL中的map容器)即一小块连续的空间,该空间中每个元素都是指针,指向另一段(较大的)区域,这个区域称为缓冲区,缓冲区用来保存deque中的数据。因此deque在随机访问和遍历数据会比vector慢。
#include <deque>
#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
deque<int> ideq(20); //Create a deque ideq with 20 elements of default value 0
deque<int>::iterator pos;
int i;
//使用assign()赋值 assign在计算机中就是赋值的意思
for (i = 0; i < 20; ++i)
ideq[i] = i;
//输出deque
printf("输出deque中数据:\n");
for (i = 0; i < 20; ++i)
printf("%d ", ideq[i]);
putchar('\n');
//在头尾加入新数据
printf("\n在头尾加入新数据...\n");
ideq.push_back(100);
ideq.push_front(i);
//输出deque
printf("\n输出deque中数据:\n");
for (pos = ideq.begin(); pos != ideq.end(); pos++)
printf("%d ", *pos);
putchar('\n');
//查找
const int FINDNUMBER = 19;
printf("\n查找%d\n", FINDNUMBER);
pos = find(ideq.begin(), ideq.end(), FINDNUMBER);
if (pos != ideq.end())
printf("find %d success\n", *pos);
else
printf("find failed\n");
//在头尾删除数据
printf("\n在头尾删除数据...\n");
ideq.pop_back();
ideq.pop_front();
//输出deque
printf("\n输出deque中数据:\n");
for (pos = ideq.begin(); pos != ideq.end(); pos++)
printf("%d ", *pos);
putchar('\n');
return 0;
}
例题一【Magic Master】
我觉得这道题对语文不好的我来说真心有点难,看了n久才知道这道题是要逆着来的。下面有几个重点
- 一般来说反着过来做,第一步和第二步要反过来,所以我们是先做第二步,再做第一步,因此在第二步的循环判断的时候a.size()>1
- 对于第一步的将顶端的牌放到John的手上牌的顶端还是照常,因为这是一个转移操作,是不需要因为是逆操作而做相反动作的。与之相对比的是第二步的(a),b表示的是桌面上的牌,a表示的是John手上的牌,要对b进行将头放到尾的操作,那么它的逆操作就是从尾放到头。
所以整个过程就是,(1)从顶部取出一张牌放到桌上。(2)将桌上的后面的牌放到前面。 (3)再将最后一张牌取出放到桌子上。
菜鸟的双向队列版本
#include <iostream>
#include <cstdio>
#include <deque>
using namespace std;
int t,n,m,k;
deque <int>a,b;
int main(void)
{
scanf("%d",&t);
while(t--){
a.clear();
b.clear();
cin>>n>>m>>k;
for(int i=n-1;i>=1;i--)
a.push_back(i);
b.push_back(n);
while(a.size()>1){
b.push_front(a.front());
a.pop_front();
for(int i=0;i<m;i++){
b.push_front(b.back());
b.pop_back();
}
}
//这里我是真的搞不懂,为什么有a.pop_front()就报错?
b.push_front( a.front());
a.pop_front();
/* for(int i=0;i<n;i++)
cout<<b[i]<<" ";
cout<<endl;
*/
for(int i=0;i<k;i++){
int x;
cin>>x;
cout<<b[x-1]<<endl;
}
}
return 0;
}
大佬的简易版本
#include <iostream>
#include <cstdio>
#include <deque>
using namespace std;
int t,n,m,k;
deque <int>q;
int main(void)
{
scanf("%d",&t);
while(t--){
cin>>n>>m>>k;
q.clear();
q.push_front(n);
for(int i=n-1;i>1;i--){
q.push_front(i);
for(int i=0;i<m;i++){
q.push_front(q.back());
q.pop_back();
}
}
q.push_front(1);
while(k--){
int x;
cin>>x;
cout<<q[x-1]<<endl;
}
}
return 0;
}