您的位置:首页 > 其它

顺序队列的入队操作

2012-08-05 00:00 831 查看
昨天我们定义了顺序队列的ADT,还写了顺序队列的初始化函数。那么现在我们马上来看队列的一个重要的基础操作:入队。想想,入队的算法应该怎么写?

额……想想。首先队列是线性表,用数组实现,所以首先要判断队列是不是满的。

如何判断一个队列是否满的?

假设我们在军训中排队,每个人报数。一个队列只能站10个人,从1报到10,队就满了。后来呢,队头的两个人出队了,然后又补充了两个新队员,那么这时候的报数是3到12。这时队列也是满的。

是不是有点思路了?没错,满足(12 + 1) mod 10 = 0就能说明队满了。所以条件就是 (Q->rear+1)%MAXSIZE == Q->front ,队头指针加1再mod队列长度,如果值为0,就说明队满。程序如下:

/* 若队列未满,则插入元素e为Q新的队尾元素 */
Status EnQueue(SqQueue *Q,QElemType e)
{
if ((Q->rear+1)%MAXSIZE == Q->front)	/* 队列满的判断 */
return ERROR;
// to do ……
}


嗯,如果队不满,我们就可以入队了。入队的思路就是,先给队尾元素赋值,然后再将队尾指针向后移动一位。比如从空队列开始,此时 Q->front == Q->rear,这个时候插入元素的话,其实就是给 data[Q->rear] 赋值 e,然后队尾指针 Q->rear 向后移动一位重新赋值。问题是如何赋值呢?

我们在定义队列的结构体的时候并没有一个单独的变量来记录队列的长度,比如前面谈到栈的时候,我们在定义结构体的时候,多定义了一个 int count; 来记录长度,这时移动指针也是很方便。

虽然我们在定义队列的时候没这个长度变量,但是我们可以通过模计算来取得我们需要的。将队尾指针向后移动一位?很简单,Q->rear = (Q->rear+1)%MAXSIZE; 即可。

所以入队函数设计成这样:

/* 若队列未满,则插入元素e为Q新的队尾元素 */
Status EnQueue(SqQueue *Q,QElemType e)
{
if ((Q->rear+1)%MAXSIZE == Q->front)	/* 队列满的判断 */
return ERROR;
Q->data[Q->rear]=e;			/* 将元素e赋值给队尾 */
Q->rear=(Q->rear+1)%MAXSIZE;/* rear指针向后移一位置, */
/* 若到最后则转到数组头部 */
return  OK;
}


原来这么简单。我把遍历操作也补上吧,一会给个完整的程序。


#include "stdio.h"
#include "stdlib.h"
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存储空间初始分配量 */
typedef int Status;
/* QElemType类型根据实际情况而定,这里假设为int */
typedef int QElemType;
/* 循环队列的顺序存储结构 */
typedef struct
{
QElemType data[MAXSIZE];
int front; /* 头指针 */
int rear; /* 尾指针,若队列不空,指向队列尾元素的下一个位置 */
}SqQueue;
/* 初始化一个空队列Q */
Status InitQueue(SqQueue *Q)
{
Q->front=0;
Q->rear=0;
return OK;
}
Status visit(QElemType c)
{
printf("%d ",c);
return OK;
}
/* 从队头到队尾依次对队列Q中每个元素输出 */
Status QueueTraverse(SqQueue Q)
{
int i;
i=Q.front;
while((i+Q.front)!=Q.rear)
{
visit(Q.data[i]);
i=(i+1)%MAXSIZE;
}
printf("\n");
return OK;
}/* 若队列未满,则插入元素e为Q新的队尾元素 */ Status EnQueue(SqQueue *Q,QElemType e) { if ((Q->rear+1)%MAXSIZE == Q->front) /* 队列满的判断 */ return ERROR; Q->data[Q->rear]=e; /* 将元素e赋值给队尾 */ Q->rear=(Q->rear+1)%MAXSIZE;/* rear指针向后移一位置, */ /* 若到最后则转到数组头部 */ return OK; }int main()
{
int opp, j;
SqQueue Q;
QElemType d;
InitQueue(&Q);
printf("\n1.给队列附初始值 \n2.遍历队列 \n3.入队 ");
printf("\n0.退出 \n请选择你的操作:\n");
while(opp != '0')
{
scanf("%d",&opp);
switch(opp)
{
case 1:
srand(time(0));
for(j=1; j

延伸阅读

此文章所在专题列表如下:

栈的定义与大概理解

栈的抽象数据类型ADT

顺序栈:栈的顺序存储结构

顺序栈的进栈操作

顺序栈的出栈操作

获取顺序栈的栈顶元素

链栈:栈的链式存储结构

链栈的进栈操作

链栈的初始化与遍历

链栈的出栈操作

链栈的置空操作与判断链栈是否为空

为什么要使用栈这种数据结构

递归,栈的重要应用之一

栈是如何实现递归的

接触后缀表达式(逆波兰表示法)

图解后缀表达式的计算过程

将中缀表达式转化为后缀表达式

开始学习队列这个数据结构

队列的抽象数据类型ADT

顺序队列:队列的顺序存储结构

顺序队列的入队操作

顺序队列的出队操作

顺序队列置空与判断操作

队列顺序存储结构的不足

关于循环队列的一些讲解

链队列:队列的链式存储结构

链队列的初始化操作

链队列的入队操作

链队列的出队操作

补完链队列的其它常见操作

循环队列与链队列的优劣势

本文地址:http://www.nowamagic.net/librarys/veda/detail/2344,欢迎访问原出处。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  队列 入队