顺序队列的实现及其应用

一、概念

  • 队列是允许在两端(队头、队尾)进行插入和读出操作线性表

  • 默认情况下队尾插入,队头读出 (这一点和排队很像),先进先出FIFO

  • 队中没有元素时称为空队

  • 当队列两端都允许插入、读出 时,称为双端队列

二、顺序队列的结构模型

cpp 复制代码
typedef int data_t

#define N (128)	//队列容量
    
typedef struct{
    data_t data[N]; //数组作为队列的存储空间
    int front; //队头 指向队头元素
    int rear;  //队尾 指向队尾元素的下一个位置
}sequeue;

2.1队空

刚创建的空队列就是如此,由此也可以得到空队的条件就是:front == rear

2.2入队

假设入队D1、D2、D3

这里入队的逻辑是,先入队元素,rear再移动(实际上也是rear++)

特殊情况是:入队的元素过多导致rear溢出,可以利用取余操作来避免这一风险

即:rear = (rear+1) % N

因此,这样一来也促成了**"循环队列"**

2.3出队

依次出队D1、D2

这里出队的逻辑是:先出队元素,front再移动

这里出队实际上也会遇到溢出情况,因为是循环队列,所以front的移动也对N取余即可

2.4满队

当队列再入队D7时,rear会移动到和front相同位置,但此刻是"满队",会和"空队"冲突

为了避免这个情况,D7不允许入队,解决办法是:入队时进行判断,如果rear+1等于front,那么不执行入队操作

三、顺序队列的实现

cpp 复制代码
typedef int data_t;
#define N 128

typedef struct{
    data_t data[N]; //数组作为队列的存储空间
    int front; //队头 指向队头元素
    int rear;  //队尾 指向队尾元素的下一个位置
}sequeue;

sequeue *queue_create(void);            //创建队列
int enqueue(sequeue *q, data_t value);  //入队
data_t dequeue(sequeue *q);             //出队
int queue_is_empty(sequeue *q);         //判断队列是否为空
int queue_is_full(sequeue *q);          //判断队列是否已满
int queue_clear(sequeue *q);            //清空队列
sequeue *queue_free(sequeue *q);        //释放队列空间

3.1创建

cpp 复制代码
sequeue *queue_create(void)
{
    sequeue *q;

    //申请空间
    q = (sequeue*)malloc(sizeof(sequeue));
    if(q == NULL)
    {
        printf("queue_create:malloc space failed!\n");
        return NULL;
    }
    //初始化
    memset(q->data,0,sizeof(q->data));
    q->front = 0;
    q->rear = 0;

    return q;
} 

3.2入队

cpp 复制代码
int enqueue(sequeue *q, data_t value)
{
    //参数检查
    if(q == NULL)
    {
        printf("enqueue:queue passed is NULL!\n");
        return -1;
    }
    //判断队列是否已满
     if( (( q->rear + 1) % N) == q->front)
    {
        printf("enqueue:queue is full!\n");
        return -1;
    }
    //入队
    q->data[q->rear] = value;
    //队尾++ 对N取余保证不溢出
    q->rear = (q->rear + 1) % N;

    return 1;
}

3.3出队

cpp 复制代码
data_t dequeue(sequeue *q) 
{
    data_t ret;//保存出队元素

    //参数检查
    if(q == NULL)
    {
        printf("dequeue:queue passed is NULL!\n");
        return -1;
    }

    //应由程序判断队列是否为空,这里就不判断了
    ret = q->data[q->front];
    //front移动
    q->front = (q->front + 1) % N;

    return ret;
}

3.4判断队列是否为空

cpp 复制代码
int queue_is_empty(sequeue *q)   
{
    //参数检查
    if(q == NULL)
    {
        printf("queue_is_empty:queue passed is NULL!\n");
        return -1;
    }

    return (q->front==q->rear? 1 : 0);
}

3.5判断队列是否已满

cpp 复制代码
int queue_is_full(sequeue *q)    
{
    //参数检查
    if(q == NULL)
    {
        printf("queue_is_full:queue passed is NULL!\n");
        return -1;
    }    

    //判断队列是否已满
    if( (( q->rear + 1) % N) == q->front)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

3.6清空队列

cpp 复制代码
int queue_clear(sequeue *q)       
{
    //参数检查
    if(q == NULL)
    {
        printf("queue_clear:queue passed is NULL!\n");
        return -1;
    }

    q->front = 0;
    q->rear = 0;

    return 1;
}

3.7释放队列空间

cpp 复制代码
sequeue *queue_free(sequeue *q)    
{
    //参数检查
    if(q == NULL)
    {
        printf("queue_free:queue passed is NULL!\n");
        return NULL;
    }

    free(q);
    q = NULL;

    return NULL;//传回主程序,避免野指针
}

四、应用

cpp 复制代码
#include <stdio.h>
#include "sequeue.h"

int main(void)
{
        sequeue *q;

        q = queue_create();
        if(q == NULL)
        {
                printf("queue_create:create failed!\n");
                return -1;
        }

        enqueue(q,10);
        enqueue(q,20);
        enqueue(q,30);
        enqueue(q,40);
        enqueue(q,50);
        enqueue(q,60);

        while(!queue_is_empty(q))
        {
                printf("dequeue:%d\n",dequeue(q));
        }

        q = queue_free(q);

        return 0;
}
相关推荐
EnigmaCoder10 分钟前
单链表:数据结构中的灵活“链条”
c语言·数据结构·学习
南宫生32 分钟前
力扣每日一题【算法学习day.130】
java·学习·算法·leetcode
sjsjs111 小时前
【数据结构-并查集】力扣1722. 执行交换操作后的最小汉明距离
数据结构·算法·leetcode
冠位观测者1 小时前
【Leetcode 每日一题 - 扩展】1512. 好数对的数目
数据结构·算法·leetcode
南宫生1 小时前
力扣每日一题【算法学习day.133】
java·学习·算法·leetcode
_Itachi__1 小时前
LeetCode 热题 100 560. 和为 K 的子数组
数据结构·算法·leetcode
SRA.2 小时前
STM32——HAL库开发笔记22(定时器3—呼吸灯实验)(参考来源:b站铁头山羊)
笔记·stm32·嵌入式硬件
SRA.2 小时前
STM32——HAL库开发笔记21(定时器2—输出比较)(参考来源:b站铁头山羊)
笔记·stm32·嵌入式硬件
大模型铲屎官2 小时前
哈希表入门到精通:从原理到 Python 实现全解析
开发语言·数据结构·python·算法·哈希算法·哈希表
C语言扫地僧2 小时前
RPC 框架项目剖析
c++·网络协议·学习·rpc