数据结构——顺序存储的循环队列

## 队列的定义

**队列是只允许在一端进行插入操作,在另一端进行删除操作的线性表,允许插入(也称入队,进队)的一端叫队尾,允许删除(也叫出队)的一端叫做对头,队列具有先进先出的特点。**

**在顺序队列中,随着队列的插入删除操作,整个队列向数组中下标较大的位置移动,从而产生队列的单向移动性。当元素被插入到数组中下标最大的位置时,数组的空间就用完了,尽管此时数组的低端还有空闲空间,这种现象叫假溢出。

为了解决这种假溢出,可以将存储队列的数组看做成头尾相接的循环结构,即循序队列。**

## 顺序存储的循环队列

```

#include

#include

//定义数组的最大长度

#define QueueSize 100

//定义队列元素的数据类型,为int

typedef int DataType;

typedef struct {

DataType data[QueueSize];

int front;

int rear;

}CirQueue;

//循环队列的初始化

void InitQueue(CirQueue ** Q){

(*Q)->front = (*Q)->rear = QueueSize-1;

}

//循环队列的销毁:循环队列是静态存储分配,

//在循环队列变量退出作用域自动释放所占内存单元,顺序存储的循环队列无需销毁

//入队操作

int EnQueue(CirQueue ** Q , DataType x){

if(((*Q)->rear + 1)%QueueSize == (*Q)->front){

printf("上溢错误,入队失败");

return 0;

}

//队尾位置在循环意义上加1

(*Q)->rear = ((*Q)->rear + 1) % QueueSize;

//在队尾插入元素

(*Q)->data[(*Q)->rear] = x;

return 1;

}

//出队操作

int DeQueue(CirQueue ** Q,DataType * ptr){

if((*Q)->rear == (*Q)->front){

printf("下溢错误,删除失败");

return 0;

}

(*Q)->front = ((*Q)->front + 1)%QueueSize;

*ptr = (*Q)->data[(*Q)->front];

return 1;

}

int GetHead(CirQueue * Q,DataType * ptr){

int i;

if(Q->rear == Q->front){

printf("下溢错误,取队头失败");

}

i = (Q->front + 1)%QueueSize;

*ptr = Q->data[i];

return 1;

}

int Empty(CirQueue * Q)

{

if(Q->rear == Q->front){

return 1;

}else{

return 0;

}

}

int main(){

DataType x;

CirQueue * Q;

InitQueue(&Q);

EnQueue(&Q,5);

EnQueue(&Q,4);

EnQueue(&Q,3);

EnQueue(&Q,2);

EnQueue(&Q,1);

if(GetHead(Q,&x) == 1)

printf("当前队头元素为:%d\n",x);

if(DeQueue(&Q,&x) == 1)

printf("执行一次出队操作,出队元素为%d\n",x);

if(GetHead(Q,&x) == 1)

printf("当前队头元素为:%d\n",x);

if(DeQueue(&Q,&x) == 1)

printf("执行一次出队操作,出队元素为%d\n",x);

if(GetHead(Q,&x) == 1)

printf("当前队头元素为:%d\n",x);

if(Empty(Q) == 1){

printf("队列为空\n");

}else{

printf("队列非空\n");

}

return 0;

}

![在这里插入图片描述](https://img-blog.csdnimg.cn/20181028165935250.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2N6eGxqeTk5OQ==,size_27,color_FFFFFF,t_70)