定义
顺序队列是队列的顺序存储结构,顺序队列实际上是运算受限的顺序表。和顺序表一样,顺序队列用一个向量空间来存放当前队列中的元素。由于队列的队头和队尾的位置是变化的,设置两个指针front和rear分别指示队头元素和队尾元素在向量空间中的位置,它们的初值在队列初始化时均应设置为0。
称为"先进先出"线性表:插入操作只能在队尾进行,删除操作只能在队首进行。 而循环队列是队列的一种特殊形式,循环队列(也被称为环形队列)是一种线性数据结构,其操作表现基于先进先出原则,并且队尾被连接在队首之后以形成一个循环。
概述操作
- Initqueue(Q):初始化。
- enqueue(Q,x):入队。
- dequeue(Q):出队。
- isfull(Q):判断队列是否为满。
- isempty(Q):判断队列是否为空。
- getHead(Q):取队头元素。
- getLength(Q length):队列长度
- printQueue(Q):输出队列元素
实现
结构体
typedef int DataType;
typedef struct
{
DataType data[MAXSIZE];
int front;
int rear;
}CirclesQueue;
初始化
/*循环队列初始化*/
int init(CirclesQueue* Q) {
Q->front = Q->rear = 0;
return 0;
}
入队
/*入队*/
int enqueue(CirclesQueue* Q, DataType x) {
if (isfull(Q)) {
printf("队列已满!100001\n");
return 100001;
}
Q->rear = (Q->rear + 1) % MAXSIZE;
Q->data[Q->rear] = x;
return 0;
}
出队
/*出队*/
int dequeue(CirclesQueue* Q, DataType* x) {
if (isempty(Q)) {
printf("队列为空!100002\n");
return 100002;
}
Q->front = (Q->front + 1) % MAXSIZE;
*x = Q->data[Q->front];
return 0;
}
是否为空
/*队空*/
int isempty(CirclesQueue* Q) {
return (Q->front == Q->rear) ? 1 : 0;
}
队列长度
/*队列长度*/
int getLength(CirclesQueue* Q, DataType* length) {
*length = (Q->rear - Q->front + MAXSIZE) % MAXSIZE;
return 0;
}
是否为满
/*队满?*/
int isfull(CirclesQueue* Q) {
return (Q->rear + 1) % MAXSIZE == Q->front ? 1 : 0;
}
取队首元素
/*取队首元素*/
int getHead(CirclesQueue* Q, DataType* x) {
if (isempty(Q)) {
printf("队列为空!100002\n");
return 100002;
}
*x = Q->data[(Q->front + 1) % MAXSIZE];
return 0;
}
输出队列元素
/*输出队列元素*/
void printQueue(CirclesQueue* Q) {
if (isempty(Q)) {
printf("队列为空!\n");
return;
}
int front = (Q->front + 1) % MAXSIZE;
while (front != (Q->rear + 1) % MAXSIZE) {
printf("%d ", Q->data[front]);
front = (front + 1) % MAXSIZE;
}
}
运行结果
初始化
入队
出队
是否为空
是否为满
输出队列长度
取队首元素
输出队列元素
完整代码
main.c
#include <stdio.h>
#include "CirclesQueue.h"
int main(int argc, char* argv[]) {
CirclesQueue Q;
DataType x, length;
int cmd;
char yn;
do {
printf("-----------循环队列演示重生我是特种兵DDQ-----------\n");
printf(" 1. 初始化\n");
printf(" 2. 入队\n");
printf(" 3. 出队\n");
printf(" 4. 队空\n");
printf(" 5. 队满\n");
printf(" 6. 队列长度\n");
printf(" 7. 取队首长度\n");
printf(" 8. 输出队列元素\n");
printf(" 0. 退出\n");
printf(" 请选择(0~8):");
scanf_s("%d", &cmd);
switch (cmd) {
case 1:
init(&Q);
printf("队列已初始化!\n");
break;
case 2:
printf("请输入要入队的元素x=");
scanf("%d", &x);
if (!enqueue(&Q, x)) {
printf("元素x=%d已入队\n", x);
}
break;
case 3:
printf("确定要出队(出队会将删除对首元素, y or n, n)?");
fflush(stdin);
scanf_s("%c", &yn);
if (yn == 'y' || yn == 'Y') {
if (!dequeue(&Q, &x)) {
printf("队首元素【%d】已出队!\n", x);
}
}
break;
case 4:
if (isempty(&Q)) {
printf("%s\n", "队列为空!");
}
else {
printf("%s\n", "队列不为空!");
}
break;
case 5:
if (isfull(&Q)) {
printf("%s\n", "队列已满!");
}
else {
printf("%s\n", "队列未满!");
}
break;
case 6:
if (!getLength(&Q, &length)) {
printf("%d\n", length);
}
break;
case 7:
if (!getHead(&Q, &x)) {
printf("%d\n", x);
}
break;
case 8:
printQueue(&Q);
printf("\n");
break;
}
} while (cmd != 0);
return 0;
}
CirclesQueue.h
/*
CirclesQueue.h
循环队列
*/
#define MAXSIZE 10
typedef int DataType;
typedef struct
{
DataType data[MAXSIZE];
int front;
int rear;
}CirclesQueue;
/*循环队列初始化*/
int init(CirclesQueue*Q);
/*入队*/
int enqueue(CirclesQueue*Q, DataType x);
/*队满?*/
int isfull(CirclesQueue*Q);
/*出队*/
int dequeue(CirclesQueue*Q, DataType*);
/*队空*/
int isempty(CirclesQueue*Q);
/*队列长度*/
int getLength(CirclesQueue*Q, DataType* length);
/*取队首元素*/
int getHead(CirclesQueue*Q, DataType* x);
/*输出队列元素*/
void printQueue(CirclesQueue*Q);
CirclesQueue.c
/*
CirclesQueue.c
*/
#include "CirclesQueue.h"
#include <stdio.h>
/*循环队列初始化*/
int init(CirclesQueue* Q) {
Q->front = Q->rear = 0;
return 0;
}
/*入队*/
int enqueue(CirclesQueue* Q, DataType x) {
if (isfull(Q)) {
printf("队列已满!100001\n");
return 100001;
}
Q->rear = (Q->rear + 1) % MAXSIZE;
Q->data[Q->rear] = x;
return 0;
}
/*队满?*/
int isfull(CirclesQueue* Q) {
return (Q->rear + 1) % MAXSIZE == Q->front ? 1 : 0;
}
/*出队*/
int dequeue(CirclesQueue* Q, DataType* x) {
if (isempty(Q)) {
printf("队列为空!100002\n");
return 100002;
}
Q->front = (Q->front + 1) % MAXSIZE;
*x = Q->data[Q->front];
return 0;
}
/*队空*/
int isempty(CirclesQueue* Q) {
return (Q->front == Q->rear) ? 1 : 0;
}
/*队列长度*/
int getLength(CirclesQueue* Q, DataType* length) {
*length = (Q->rear - Q->front + MAXSIZE) % MAXSIZE;
return 0;
}
/*取队首元素*/
int getHead(CirclesQueue* Q, DataType* x) {
if (isempty(Q)) {
printf("队列为空!100002\n");
return 100002;
}
*x = Q->data[(Q->front + 1) % MAXSIZE];
return 0;
}
/*输出队列元素*/
void printQueue(CirclesQueue* Q) {
if (isempty(Q)) {
printf("队列为空!\n");
return;
}
int front = (Q->front + 1) % MAXSIZE;
while (front != (Q->rear + 1) % MAXSIZE) {
printf("%d ", Q->data[front]);
front = (front + 1) % MAXSIZE;
}
}
总结
循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值