详解栈的顺序队列

定义

顺序队列是队列的顺序存储结构,顺序队列实际上是运算受限的顺序表。和顺序表一样,顺序队列用一个向量空间来存放当前队列中的元素。由于队列的队头和队尾的位置是变化的,设置两个指针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;
    }
}

总结

循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值