数据结构之 (单向)队列:
理解:可类比为平时排队的情形,队伍中人员的变动,只发生在队头或者队尾,即队头的人离开或队尾有新的人加入。
满足先进先出【FIFO】的原则。
实现的基本思想:使用两个整形变量 head 和 tail, head代表头一个元素, tail代表最后一个元素的后一位【此时便于用head == tail来判断队列是否为空而不导致混淆】
增加元素:加入元素后再使得tail++即可;
删除元素:head++即可;【此时元素在内存中依然存在,只是有效的部分改变】。
C++STL库中已经有队列的实现
具体的内容在MoreWindows的博客中已有描述:
STL系列之三 queue 单向队列【
http://blog.csdn.net/morewindows/article/details/6950917】
下面以一个题目作为举例以加深理解:
Description
桌子上有一叠牌,从第一张牌(即位于顶面的牌)开始从上往下依次编号为1~n。当至少剩下两张牌时进行以下操作:把第一张牌扔掉,然后把新的第一张牌放到整叠牌的最后。输入n,输出每次能掉的牌,以及最后剩下的牌。
Input
第一行为一个整数t(0<t<20),表示测试用例个数。以下t行每行包含一个整数n(0<n<40),为一个测试用例的牌数。
Output
为每个测试用例单独输出一行,该行中依次输出每次掷出的牌的编号以及最后剩下牌的编号,每个牌编号后跟着一个空格。
分析: 直接对题目所描述的过程进行模拟。
#include<iostream>
using namespace std;
int main()
{
int n;
int k;
int a[1000];
int head;
int tail;
cin >> k;
while(k--)
{
cin >> n;
head = 0; //初始化,指向第一个元素 ;
tail = n; //初始化,只想最后一个元素的后一位;
for(int i=0;i<n;i++)
a[i] = 1+i;
while(head<tail)
{
cout << a[head] << " ";//打出第一张牌
head++; //删除此牌(有效位数缩短)
a[tail] = a[head];//下一张牌移到末尾
tail++;//末尾相应改变
head++;//牌被移除
}
cout << endl;
}
return 0;
}
采用STL库的实现
#include<iostream>
#include<queue> //在STL中的队列
using namespace std;
int main()
{
queue<int> que;
int n;
int num;
cin >> n;
while(n--)
{
cin >> num;
for(int i=1;i<=num;i++)
que.push(i); //在末尾加入牌
while(!que.empty())
{
cout << que.front() <<" ";
que.pop();//删除第一张牌
que.push(que.front());//把头一张牌的值移动到最后
que.pop();
}
cout << endl;
}
return 0;
}