#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
typedef int ElemType;
#define MaxSize 10//队列的定义
typedef struct SqQueue
{ElemType data[MaxSize];int front, rear;//front为头指针,rear为尾指针。这里并不是真正的“指针”
}SqQueue;SqQueue q;
void InitQueue(SqQueue* q);//初始化队列
bool EnQueue(SqQueue* q, ElemType x);//入队操作
bool PopQueue(SqQueue* q);//出队操作
bool Gethead(SqQueue* q);//取队头元素
void PrintQueue(SqQueue* q);//打印队列元素void InitQueue(SqQueue* q)//初始化队列
{q->front = q->rear=0;printf("队列初始化成功\n");
}bool EnQueue(SqQueue* q,ElemType x)//入队操作
{if ((q->rear + 1) % MaxSize == q->front)printf("队列已满,无法完成入队操作\n");else{q->data[q->rear] = x;q->rear = ((q->rear) + 1) % MaxSize;//因为是循环队列,所以采用这种方式使队尾指针后移printf("入队成功\n");}
}bool PopQueue(SqQueue* q) //出队操作
{if (q->rear == q->front){printf("该队列为空,无法完成出队操作\n");}else {int x;x = q->data[q->front];q->front = ((q->front) + 1) % MaxSize;//使队头指针后移printf("出队成功\n");}
}bool Gethead(SqQueue* q)//取队头元素
{if (q->rear == q->front){printf("该队列为空,无法完成出队操作\n");}else{int x;x = q->data[q->front];printf("队头元素为%d",x);}
}void PrintQueue(SqQueue q)//打印队列元素
{while (q.front != q.rear){printf("%d ", q.data[q.front]);q.front = (q.front + 1) % MaxSize;}
}
所述代码都是基于队尾指针指向队尾元素后一个位置实现的
队列:
1.只能从一段进行插入,另一端进行删除
2.注意循环队列q->rear=((q->rear)+1)%MaxSize是使指针后移的操作
判断队列已满/为空的操作
方法一:这种判空方式就是上面代码所用的,缺点是会牺牲一个存储单元(因为我们是用rear指针的下一个位置是front来判断队列是否已满)
方法二:定义一个变量来记录队列的长度,入队成功size++,出队size--,
此时队满的判断:size==MaxSize;
方法三:定义一个tag变量来记录最近一次执行的是插入还是删除操作
tag=1表示是插入操作
tag=0表示是删除操作
若rear==front && tag==1 则队列已满
若rear==front && tag==0 则队列为空
补充:
求队列元素的个数
int length(SqQueue L)
{return ((rear+MaxSize-front)%MaxSize);
}