队列分为顺序队列和循环队列;
每次插入,指针rear(队尾)加一,每次删除,指针front(队头)加一;
循环队列:
初始化时,rear = front=0,当队列不为空时,front指向队列中的第一个元素,rear指向队列中最后一个元素的下一个位置,当队列满时 rear=front,但不一定是位置0;
插入后rear+1,删除后front+1,但是,无论是删除还是插入,一旦rear或front加一超过了所分配的空间,则让指针指向这片空间的起始位置;设所分配的空间为Maxsize,一旦rear+1,或front+1 =Maxsize, 则rear或front指向起始位置。
因此,循环序列判空的方法是rear = front; 判满的方法是 (rear+1)%Maxsize ==front;
进队列步骤:
1.判断队列是否满,即,rear+1是否等于front,若等于则队列已满,不允许进入;
2. 若不满,则将值保存至rear+1的位置 ; 从这里也可以看出,循环数列所能存储的值其实是最大值-1。
void EnQueue(Queue *Q, int key)
{
if ( (Q->rear+1) % Q->maxsize == Q->front) //此时队列没有空间 取余保证,当quil=queuesize-1时,再转回0
{
printf("the queue has been filled full!");
}
else
{
Q->q[Q->rear] = key;
Q-> rear =(Q->rear+1) % Q->maxsize;
}
}
出队列步骤:
1.判断数列是否为空;
2, 将front现在的时间表保存至temp;
3,将front指针后移一个;
4. 返回temp;
int DeQueue(Queue *Q)
{
int tmp;
if(Q->rear== Q->front) //判断队列不为空
{
printf("the queue is NULL\n");
}
else
{
tmp = Q->q[q->front];
Q->front= (Q->front+1) % Q->maxsize;
}
return tmp;
}
栈和队列的应用
在日常生活中,很多问题可以归结到栈和队列的应用问题。例如,排队购物的现象就可以看做是队列。在计算机学科的应用中,栈和队列的应用就更多了,例如,编译系统、消息队列等。
栈的应用
栈具有相当广泛的实际应用,例如,可以颠倒数据串的次序、为回溯算法提供支持、实现自动机等。
1.编译应用
栈可以应用于括号匹配、行编辑器、表达式求值、算法优先文法等编译程序中。例如,在表达式中,一般存在大、中、小三种括号,分别定义为“{}”、“[]”和“()”,要求其只能自我匹配,不能交互匹配,比如“{[()]}”、“[()()()]”等均为正确匹配,而“({]”、“(])[”、“)(]}”等均为错误匹配。
2.转置应用
一串数据全部进入栈后再全部出栈,将得到一个次序完全相反的数据串,这是栈的特性之一。因此,栈可以应用于转置操作,例如,数的进制转换等。
例子:已知线性链表L,请按从表尾到表头的顺序输出元素。
【解析】从头到尾遍历链表,同时将链表元素入栈,再依次出栈,并打印元素信息即可。
3.迷宫问题
迷宫问题是指在迷宫中从入口寻找出口的问题。此类问题的本质是将迷宫建模成图,将迷宫中的点建模为图中的点,将迷宫中相连并且相通的两点建模为图中的一条边,一般采用矩阵方式存储图,这样迷宫求解就转化为图的遍历,采用回溯法穷举所有从入口点到出口点之间的路径即可。
迷宫问题求解算法中一般使用一个栈来存储访问过的顶点信息,栈中元素(即顶点信息)由顶点位置和搜索方向两部分组成,前者记载该顶点在迷宫中的位置,后者记载下一个顶点的访问方向,例如,右、下、左、上四个相连的方向,编程时可分别使用枚举类型enum表示。
队列的应用
队列是一种相当实用的数据结构,可应用于生产、生活的各个方面,例如,共享打印机、消息队列和广度优先搜索等。
1.共享打印机
目前,打印机提供的网络共享打印功能采用了缓冲池技术,队列就是实现这个缓冲技术的数据结构支持。每台打印机具有一个队列(缓冲池),用户提交打印请求被写入到队列尾,当打印机空闲时,系统读取队列中第一个请求,打印并删除之。这样,利用队列的先进先出特性,就可完成打印机网络共享的先来先服务功能。
2.消息队列
操作系统中的消息队列也是队列的应用之一,消息队列遵循先进先出的原则,如图2-5所示,发送进程将消息写入队列尾,接收进程则从队列头读取消息。
#include
using namespace std;
typedef struct
{
char name[20];
char sex; //性别,'F'表示女性,'M'表示男性
} Person;
void DancePartner(Person dancer[],int num)
{
//结构数组dancer中存放跳舞的男女,num是跳舞的人数。
Person p;
queue Mdancers,Fdancers;
for(int i = 0; i < num; i++)
{
//依次将跳舞者依其性别入队
p=dancer[i];
if(p.sex=='F')
Fdancers.push(p); //排入女队
else
Mdancers.push(p); //排入男队
}
printf("跳舞的伙伴是: \n \n");
while(!(Fdancers.empty()||Mdancers.empty()))
{
//依次输入男女舞伴名
p=Fdancers.front(); //获取女队第一人
Fdancers.pop(); //出队
printf("%s ",p.name); //打印出队女士名
p=Mdancers.front(); //获取男队第一人
Mdancers.pop(); //出队
printf("%s\n",p.name); //打印出队男士名
}
if(!Fdancers.empty())
{
//输出女士剩余人数及队头女士的名字
printf("\n 有 %d 个女人等下一轮\n",Fdancers.size());
p=Fdancers.front(); //取队头
printf("%s 将是第一个得到伙伴的\n",p.name);
}
else if(!Mdancers.empty())
{
//输出男队剩余人数及队头者名字
printf("\n有%d个男人等下一轮\n",Mdancers.size());
p=Mdancers.front();
printf("%s将是第一个得到伙伴的\n",p.name);
}
else
{
printf("没有人在队列里了!");
}
}//DancerPartners
int main()
{
Person p[] = {{"A",'F'},{"B",'F'},{"C",'M'},{"D",'M'},{"E",'M'}};
DancePartner(p,5);
}