循环队列
-------------------------------------------------------------------------------------------------------------------
和顺序栈相类似,在队列的顺序储存结构中,除了用一组地址连续的存储单元依次存放从队头到队列尾的元素之外,还需设两个指针 Q.front 和 Q.rear 分别指向队列头元素和队列尾元素。
初始化队列的时候, 令 front=rear=1, 每当插入新的元素的时候的时候, rear增加1,每当删除元素的时候, front增加1。
如图3.13,称之为循环队列。
如图 a :队列头元素是 J3 ,队列尾元素是 J5.
如图 b :Q.front=Q.rear,队列是满的。
如图 c :Q.front=Q.rear ,队列为空。
(注: Q.front=Q.rear无法判定队列空间是 “空”还是“满”,)
有两种方法:
1、另设一个标志位以区别队列是“空”还是“满”。
2、少用一个元素空间,约定以“队列头指针在队列尾指针的下一位置(指环状的下一位置)上”作为 队列呈“满”状态的标志。
代码:
//头文件
#include"stdio.h"
#include"stdlib.h"
#include"malloc.h"
//宏定义
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef char QElemType;
typedef char Status;
//---------循环队列——队列的顺序存储结构---------
#define MAXQSIZE 100 //最大队列长度
typedef struct{
QElemType *base; //初始化的动态分配存储空间
int front; //头指针,若队列不为空,指向队列的头元素
int rear; //尾指针,若队列不为空,指向队列尾元素的下一个位置
}SqQueue;
//--------循环队列的基本操作的算法描述-------------
//1、初始化循环队列
Status InitQueue(SqQueue &Q){
//构造一个空队列Q
Q.base=(QElemType *)malloc(MAXQSIZE*sizeof(QElemType));
if(!Q.base) exit(OVERFLOW); //存储分配失败
Q.front=Q.rear=0;
return OK;
}
//2、求循环队列的长度,返回 Q 的元素个数,即队列的长度
Status QueueLength(SqQueue Q){
return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}
//3、插入元素e为 Q 的新的元素
Status EnQueue(SqQueue Q,QElemType e){
if((Q.rear+1)%MAXQSIZE == Q.front)
return ERROR; //队列满
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQSIZE;
return OK;
}
//4、若队列不为空,则删除 Q 的队头元素,用 e 返回其值,并返回OK ,否则返回ERROR
Status DeQueue(SqQueue &Q,QElemType &e){
if(Q.front==Q.rear) return ERROR;
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
return OK;
}
Status GetTop(SqQueue &Q, QElemType &e)
{
if (Q.rear == Q.front)
return ERROR;
e = Q.base[Q.front];
return OK;
}
Status Destroy(SqQueue Q){
free(Q.base);
Q.base=NULL;
return OK;
}