数据结构——队列
- 队列是一种先进先出的线性表(FIFO),只允许尾进头出
- 队列分为链队列和顺序队列
- 链队列采取边开辟空间边插入元素来实现
- 顺序队列在定义之后空间大小不能继续申请,所以通过将队列假象为环状空间来解决元素出队后空间不能被利用的问题。
- 将顺序队列假想为循环队列后产生了队列空满判断条件一致的问题。有以下三种解决方法:
- 一.少用一个元素空间,约定队列头指针在队尾指针下一个位置为队列满
- 二.另设标志位来区别队空,队满,初识时把tag置为0,入出队操作前检查是否对满或空,入队操作后设置为1,出队操作后设置为0
- 三.去掉rear或front中的一个,另设表示队列长度的length域区别队列空、满。此时初始化时应把length置为0,入出队操作前应根据它检查是否队空/满,入出队操作后应把它随之加1或减1。
以下代码采用牺牲一个元素空间的方法来达到队列空满判断条件不一样的目的。
一.预定义常量
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
二.队列的结构定义
#define MAXQSIZE 100
typedef int QElemType;
typedef int Status;
//循环队列的顺序存储结构
typedef struct
{
QElemType *data;
int front; //头指针
int rear;//尾指针,队列非空时,指向队尾元素的下一个位置
}SqQueue;
三.队列的基本操作
//初始化队列
Status InitQueue(SqQueue &Q)
{
Q.data=(QElemType *)malloc(MAXQSIZE*sizeof(QElemType));
if(!Q.data)
exit(OVERFLOW);
Q.front =0;
Q.rear =0;
return OK;
}
//在队尾插入元素
Status EnQueue(SqQueue &Q, QElemType e)
{
if((Q.rear+1)%MAXQSIZE == Q.front)//队列已满
return ERROR;
Q.data[Q.rear]=e;//插入队尾
Q.rear=(Q.rear +1)%MAXQSIZE;//尾部指针后移,如果到最后则转到头部
return OK;
}
//队头元素出队
Status DeQueue(SqQueue &Q, QElemType &e)
{
if(Q.front == Q.rear)//队列空
return ERROR;
e=Q.data[Q.front];//返回队头元素
Q.front=(Q.front+1)%MAXQSIZE;//队头指针后移,如到最后转到头部
return OK;
}
//清空队列
Status ClearQueue(SqQueue &Q)
{
Q.front = Q.rear =0;
return OK;
}
//判断队列是否为空
Status QueueEmpty(SqQueue Q)
{
if(Q.front == Q.rear)
return TRUE;
else
return FALSE;
}
//返回队列中的元素个数
int QueueLength(SqQueue Q)
{
return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}
//返回队头元素
Status GetHead(SqQueue Q, QElemType &e)
{
if(Q.front == Q.rear)//是否为空队列
return ERROR;
e = Q.data[Q.front];
return OK;
}
//遍历队列元素
Status QueueTraverse(SqQueue Q)
{
int i = Q.front;
while(i!= Q.rear)
{
printf("%d\t",Q.data[i]);
i=(i+1)%MAXQSIZE;
}
return OK;
}
//销毁队列
Status DestroyQueue(SqQueue &Q)
{
if(Q.data)
free(Q.data);
Q.data=NULL;
return OK;
}