循环队列的操作包括初始化、求队列的长度、入队、出队、取队头元素。下面是实现代码:
在初始化之前,先进行预定义:
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define MAXSIZE 100
typedef int Status;
typedef int ElemType;
typedef struct{
ElemType *base;
int front;
int rear;
}SqQueue;
初始化:
Status InitQueue(SqQueue *Q)
{
Q->base = (ElemType*)malloc(sizeof(ElemType)*MAXSIZE);
if (!Q->base)
exit(OVERFLOW);
Q->front = 0;
Q->rear = 0;
return OK;
}
先在内存中分配100个ElemType类型的空间,然后让Q->base指向首地址。判断Q->base是否为NULL,如果是,说明分配失败,则退出;不为NULL的时候,让Q->front和Q->rear为0。
求队列长度:
int QueueLength(SqQueue Q)
{
return (Q.rear - Q.front + MAXSIZE) % MAXSIZE;
}
将Q->rear减去Q->front再加MAXSIZE后对MAXSIZE求余能得到长度。
入队:
Status EnQueue(SqQueue *Q, ElemType e)
{
if ((Q->rear + 1) % MAXSIZE == Q->front)
return ERROR;
Q->base[Q->rear] = e;
Q->rear = (Q->rear + 1) % MAXSIZE;
return OK;
}
插入之前,先判断队列是否已满,如果已满,返回错误。将e赋值给Q->base[Q->rear](即插入队尾)。然后将队尾后移一位。
出队:
Status DeQueue(SqQueue *Q, ElemType *e)
{
if (Q->rear == Q->front)
return ERROR;
*e = Q->base[Q->front];
Q->front = (Q->front + 1) % MAXSIZE;
return OK;
}
出队之前,先判断队是否为空队,如果是,则返回错误。将队头元素Q->base[Q->front]赋值给*e,然后将队头向后移动一位即可。
取队头元素:
ElemType GetHead(SqQueue Q)
{
if (Q.front == Q.rear)
return ERROR;
return Q.base[Q.front];
}
先判断是否为空队,如果为空,则返回错误,不为空的话返回首元素。
加入main()测试:
int main(void)
{
SqQueue Q;
ElemType e;
int n;
printf("1.初始化\n2.求队列长度\n3.入队\n4.出队\n5.队头元素\n6.退出\n");
while (1)
{
printf("请选择:");
scanf("%d", &n);
switch (n)
{
case 1:
if (InitQueue(&Q) == OK)
printf("初始化成功!\n");
else
printf("初始化失败!\n");
break;
case 2:
printf("队列长度为:%d\n", QueueLength(Q));
break;
case 3:
printf("输入要插入的元素:");
scanf("%d", &e);
if (EnQueue(&Q, e) == OK)
printf("插入成功!\n");
else
printf("插入失败!\n");
break;
case 4:
if (DeQueue(&Q, &e) == OK)
printf("%d已经出队\n", e);
else
printf("失败!\n");
break;
case 5:
printf("队头元素为:%d\n", GetHead(Q));
break;
case 6:
exit(0);
}
}
return 0;
}