C语言队列的实现

目录

​编辑

(一)队列的定义,初始化及创建结点

(二)入队和出队,以及取队头队尾的数据

(三)销毁队列


队列是指只允许在一端进行插入数据操作,在另⼀端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)的特点。本篇文章的队列以链表为基础进行创建


(一)队列的定义,初始化及创建结点

复制代码
//队列的初始化
//我们先宏定义队列存储的数据类型

#define QueueDataType int           //这里我们宏定义队列存储的数据类型为int

//这里定义队列的结点
typedef struct QueueNode
{
    QueueDataType data;
    struct QueueNode* next;
}QueueNode;

//为了方便队列的出队和入队我们要新定义一个结构体,里面装着头结点和尾结点的指针。
type struct Queue
{
    QueueNode* phead;
    QueueNode* ptail;
}Queue;

这里我们定义了队列的结点和管理整个队列的结构体。关于链表形式的数据结构我们往往要单独写封装一个函数来创建结点。

复制代码
//封装一个函数,专门用来创建结点
//该函数的形参是一个数据类型,返回创建的结点的指针
QueueNode* BuyNewNode(QueueDataType val)
{
    //动态向内存申请空间
    QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
    //防止使用创建结点失败返回的NULL指针
    if (newnode == NULL)
    {
        perror("newnode malloc failed!");
        exit(1);
    }
    //给创建好的结点初始化
    newnode->data = val;
    newnode->next = NULL;

    //返回初始值
    return newnode;
}

我们还需要初始化管理整个结点的那个结构体,就叫它队列吧

复制代码
//初始化队列
void InitQueue(Queue* pq)
{
    //检查是否为空指针
    assert(pq);
    pq->phead = NULL;
    pq->ptail = NULL;
}

(二)入队和出队,以及取队头队尾的数据

入队就是从队伍的后面进去。根据这个原理我们直接写

复制代码
//队列的入队(要在初始化队列之后)
//我们通过管理整个队列的那个结构体来进行操作
//所以这里我们接受那个结构体的形参
void QueuePush(Queue* pq, QueueDataType val)
{
    //检查是不是空指针
    assert(pq);
    //我们可以通过pq来找到队伍的尾结点
    //进行入队操作。如果队列为空
    if (pq->phead == NULL)
    {
        pq->phead = pq->ptail = BuyNewNode(val);
    }
    else                //如果队列不为空,则尾插到队尾
    {
        pq->ptail->next = BuyNewNode(val);
        pq->ptail = pq->ptail->next;
    }
}

在写出队之前我们先得写一个函数来检查队列是否为空,防止队列里没有数据

复制代码
//判断队列是否为空,我们采用bool值
bool QueueEmpty(Queue* pq)
{
    assert(pq);
    return pq->phead == NULL;
}

进行出队。

复制代码
//队列的出队
void QueuePop(Queue* pq)
{    
    //检查队列是否为空
    assert(!QueueEmpty(pq));
    //如果队列只有一个元素
    if (pq->phead == pq->ptail)
    {
        pq->phead = pq->ptail = NULL;
    }
    else
    {    
        //定义一个新结点来保存出队后的头结点
        QueueNode* ptem = pq->phead->next;
        free(pq->phead); 
        pq->phead = ptem;
    }
}    

取队头就很简单了,也是直接写

复制代码
//取队头
QueueDataType QueueFront(Queue* pq)
{
    //检查队列是否为空
    assert(!QueueEmpty(pq));
    return pq->phead->data;
}

取队尾更是无需多言

复制代码
//取队尾的数据    
void QueueBack(Queue* pq)
{
    assert(!QueueEmpty(pq));
    return pq->ptail->data;
}

(三)销毁队列

最后的环节也必然是我们的销毁队列

复制代码
//销毁队列    
void QueueDestroy(Queue* pq)
{
    assert(pq);
    //新定义一个结点用来遍历队列
    QueueNode* pcur = pq->phead;
    //开始遍历链表销毁
    while (pcur)
    {    
        //再新定义一个结点来保存下一个节点
        QueueNode* ptem = pcur->next;
        free(pcur);
        pcur = ptem;
    }
    pq->phead = pq->ptail = NULL;
}
相关推荐
John_ToDebug5 小时前
判断力无法被 AI 替代,但它正在被你亲手扔掉
经验分享·笔记
2601_962218615 小时前
万象生鲜系统业财一体化底层打通技术自动生成经营账单
大数据·数据库·人工智能·python·算法
2601_966949655 小时前
为什么量化策略需要大量历史股票数据?从回测可信度理解数据规模
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
niucloud-admin5 小时前
JAVA V6 多商户商城 开发文档——插件目录结构
java·开发语言
吞下星星的少年·-·6 小时前
The 2026 ICPC Asia East Continent Online Contest (II)(构造)
数据结构·算法
滕州市燕猫虎计算机科技工作室个体工商户6 小时前
Java锁
java·开发语言
派葛穆6 小时前
Lerobot -飞特舵机ST-3215双舵机联动(ESP_NOW)
c语言
李高钢6 小时前
Python FastAPI 框架入门:从零搭建你的第一个高性能 API 服务
数据库·python·fastapi
多加点辣也没关系6 小时前
JavaScript|第31章:表单与控件
开发语言·javascript·ecmascript
上海广测检测科技有限公司6 小时前
21.5寸显示屏终端墨西哥认证详解:NOM安全、IFT无线与能效三轨合规解读
经验分享