顺序队列的基本操作

1.队列的概念

队列是只允许在一端进行插入,而在另一端进行删除的运算受限的线性表。允许删除的一端称为队头,允许插入的一端称为队尾。当队列中没有元素时称为空队列。在空队列中依次加入元素a1,a2,...,an之后,a1是队头元素,an是队尾元素。

 队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出线性表。

队列的操作原则是先进先出,后进后出。 

我们可以理解为飞机乘客进出。一般航班分为头等舱、商务舱和经济舱。乘客在登机时,头等舱的乘客可以先登机,其次是商务舱,最后是经济舱;航班到达后,也是头等舱的乘客先下机,依次是商务舱,最后是经济舱。

2.顺序队列

顺序队列是队列的顺序存储结构,顺序队列实际上是运算受限的顺序表。和顺序表一样,顺序队列用一个向量空间来存放当前队列中的元素。由于队列的队头和队尾的位置是变化的,设置两个指针front和rear分别指示队头元素和队尾元素在向量空间中的位置,它们的初值在队列初始化时均应设置为0。

顺序队列的特点:

顺序队列是通过数组实现的,通过front记录的是队列头的位置,通过rear记录的是队尾的位置,入队的时候rear向后走,出队的时候front向后走,当front=rear的时候队列是空。
但是front向后走之前前面的内存空间就不能够再次访问,所以对于顺序队列来说,在实际的工作开发过程中是不使用(复用性比较差)。

3.顺序队列的基本运算

队列的6种基本运算如下:

① InitQueue(Q):初始化操作,构造一个空队列。

② QueueEmpty(Q):判断队列是否为空。若队列为空,函数返回值为1;否则,返回值为0。

③ QueueFull(Q):判断队列是否为满。若队列已满,函数返回值为1;否则,返回值为0。

④ EnQueue(Q,x):入队操作。在队尾插入一个新元素x。

⑤ DeQueue(Q):出队操作。删除队头元素,并返回该元素。

⑥ OueueFront(Q):取队头元素。返回队头元素,但不删除。

首先我们要定义一个顺序队列类型:

typedef int DataType;
typedef struct
{
	DataType data[MAXSIZE];//DataType为数据类型
	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 isfull(CirclesQueue *Q) {
    return (Q->rear + 1) % MAXSIZE == Q->front ? 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;
    }
}

运行结果:

 

4.完整demo

 main.c

#include <stdio.h>
#include "CirclesQueue.c"

int main(int argc, char *argv[]) {
    CirclesQueue Q;
    DataType x, length;
    int cmd;
    char yn;

    do {
        printf("-----------循环队列演示-----------\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~6):");
        scanf("%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("%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.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;
    }
}

 CirclesQueue.h

#define MAXSIZE 100
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);

5.小结

队列和栈的操作原则有所不同。队列是先进先出,后进后出的原则,而栈是先进后出或后进先出的原则。它们都是插入和删除操作的位置受限制的线性表。

6.参考文献

《数据结构(C语言版)》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值