顺序队列的实现及其应用

一、概念

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

  • 默认情况下队尾插入,队头读出 (这一点和排队很像),先进先出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;
}
相关推荐
电子云与长程纠缠21 分钟前
UE5编辑器下将RenderTarget输出为UTexture并保存
学习·ue5·编辑器·虚幻
yeah__ii32 分钟前
周期字符串!
数据结构·c++·算法
violet_evergarden.36 分钟前
【51单片机】独立按键快速上手
笔记·单片机·嵌入式硬件·51单片机
艾妮艾妮1 小时前
进制的转换
c语言·开发语言·数据结构·python
菜鸟起航ing1 小时前
数据结构---哈希表(Hash Table)
java·数据结构·哈希算法·散列表
马船长1 小时前
CTFHub 技能树 Web RCE eval执行(学习记录)
学习
麻溜学习2 小时前
计网_虚拟局域网VLAN
笔记
E___V___E2 小时前
黑马 Cpp qt相关笔记
笔记
dal118网工任子仪2 小时前
32.攻防世界Web_php_include
笔记·学习·安全·web安全·网络安全
加德霍克3 小时前
Opencv之图像梯度处理和绘制图像轮廓
图像处理·人工智能·opencv·学习·计算机视觉