定义
先进先出
分类
跟栈一样,分为静态(数组)和动态(链表)
静态队列
静态队列都必须是循环队列(避免空间浪费)
以非循环队列结构图举例,如下图,rear指针必须指向队尾最后一个元素的下一个位置,这就比如链表中的头指针和尾指针一样:如果有头结点(即头指针指空)那么尾指针就指向最后一个元素,如果尾指针指向最后一个元素的下一个(即尾指针指空),那么就没有头结点。
即不管是数组还是链表,头尾两指针必须有一个指空
入队
rear=(rear+1)%数组长度
出队
front=(front+1)%数组长度
判断队列是否为空
只要front=rear则为空
判断队列是否已满
两种方式:
- 用一个表标识参数,来表示队列中的元素个数
- 浪费一个数组空间(通常用这一种)
此时如果rear和front紧挨着,则已满,即(rear+1)%数组长度==front
循环队列代码(数组)
#include <stdio.h>
#include <malloc.h>
typedef struct Queue
{
int * pBase;
int front;
int rear;
}QUEUE ,*PQUEUE;
void init(PQUEUE pQ);//初始化一般不返回任何值
bool en_queue(PQUEUE pQ,int val);
bool out_queue(PQUEUE pQ, int* pVal);
bool traverse_queue(PQUEUE pQ);
bool is_empty(PQUEUE pQ);
bool is_full(PQUEUE pQ);
int main(void)
{
QUEUE Q;
init(&Q);
int val;
en_queue(&Q,1);
en_queue(&Q, 2);
en_queue(&Q, 3);
en_queue(&Q, 4);
en_queue(&Q, 5);
/*en_queue(&Q, 6);
en_queue(&Q, 7);*/
traverse_queue(&Q);
out_queue(&Q,&val);
printf("出队元素为:%d\n",val);
traverse_queue(&Q);
return 0;
}
void init(PQUEUE pQ)
{
pQ->pBase = (int *)malloc(sizeof(int) * 6);//数组长度为6,可用长度为5,此时pQ中的pBase就有了实际意义,即指向了一个长度为24字节的数组
pQ->front = 0;
pQ->rear = 0;
}
bool is_empty(PQUEUE pQ)
{
if (pQ->front == pQ->rear)
return true;
else
return false;
}
bool is_full(PQUEUE pQ)
{
if ((pQ->rear + 1) % 6 == pQ->front)
return true;
else
return false;
}
bool en_queue(PQUEUE pQ, int val)//入队
{
if (is_full(pQ))
{
printf("队列已满,入队失败\n");
return false;
}
else
{
pQ->pBase[pQ->rear] = val;
pQ->rear = (pQ->rear + 1) % 6;
return true;
}
}
bool out_queue(PQUEUE pQ, int* pVal)
{
if (is_empty(pQ))
{
printf("队列为空,出对失败\n");
return false;
}
else
{
*pVal = pQ->pBase[pQ->front];
pQ->front = (pQ->front + 1) % 6;
return true;
}
}
bool traverse_queue(PQUEUE pQ)
{
if (is_empty(pQ))
{
printf("队列为空\n");
return false;
}
else
{
for (int i = pQ->front; i != pQ->rear; i=(i+1)%6)
{
printf("%d\n",pQ->pBase[i]);
}
return true;
}
}
应用
所有和时间有关的操作都有队列的影子