当前位置: 首页 > article >正文

【数据结构】千字深入浅出讲解队列(附原码 | 超详解)

在这里插入图片描述

🚀write in front🚀
📝个人主页:认真写博客的夏目浅石.
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝
📣系列专栏:C语言实现数据结构
💬总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🖊
✉️如果无聊的话,就来逛逛我的博客栈吧stack-frame.cn

文章目录

  • 前言
  • 一、队列的概念
  • 二、队列的结构
  • 三、队列的实现
    • 3.1结构体的定义
    • 3.2函数接口
    • 3.3初始化
    • 3.4销毁
    • 3.5入队列
    • 3.6出队列
    • 3.7计算队列大小
    • 3.8判断队列是否为空
    • 3.9取对头元素
    • 3.10取队尾元素
  • 四、队列的总代码
  • 总结


前言

今天打算给大家讲解队列这一个知识点,会把函数接口一一列举出来 并且 依次实现,这样才会更加牢固的掌握队列这一基本数据结构,话不多说,让我们一起来学习吧。


一、队列的概念

队列 链表都是一种线性表结构。

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出

FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头

数据结构图如下:
在这里插入图片描述

二、队列的结构

队列可以使用 数组链表实现,但是二者之间有不同的地方,哪一个更加适合队列呢?

我想:使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数
组头上出数据,效率会比较低

在这里插入图片描述

三、队列的实现

3.1结构体的定义

typedef char QDatatype;

typedef struct QueueNode
{
    struct QueueNode* next;
    QDatatype data;
}QNode;

由于链表的尾插比较麻烦,而队列的入数据为尾插。所以定义队列的结构体时,可以定义两个指针 head tail 分别对应 队头 和 队尾 ,tail 的引入就是方便尾插再在给定一个 size 实时记录队列的大小。


typedef struct Queue
{
    QNode* head;
    QNode* tail;
    int size;
}Queue;

3.2函数接口

void QueueInit(Queue* pq);//初始化
void QueueDestroy(Queue* pq);//销毁
void QueuePush(Queue* pq,QDatatype x);//入队列
void QueuePop(Queue* pq);//出队列
int QueueSize(Queue* pq);//计算队列大小
bool QueueEmpty(Queue* pq);//判断队列是否为空
QDatatype QueueFront(Queue* pq);//取对头元素
QDatatype QueueBack(Queue* pq);//取队尾元素

3.3初始化

要领: 队列对头队尾相等都为NULL,且size=0;

void QueueInit(Queue* pq)
{
    //暴力检查
    assert(pq);

    pq->head=pq->tail=NULL;
    pq->size=0;
}

3.4销毁

要领:cur不断遍历,然后free节点,最后处理headtail即可;

void QueueDestroy(Queue* pq)
{
    assert(pq);

    Queue* cur=pq->head;
    while(cur)
    {
        Queue* tmp=cur->next;
        free(cur);
        cur=tmp;
    }
    pq->head=pq->tail=NULL;
    pq->size=0;
}

3.5入队列

要领: 尾节点(tail)进行插入;

void QueuePush(Queue* pq,QDatatype x)
{
    Queue* newnode=(Queue*)malloc(sizeof(Queue));
    if(newnode==NULL)
    {
        perror("malloc fail");
        return;
    }
    newnode->data=x;
    newnode->nxet=NULL;
    
    if(pq->head=NULL)
    {
        assert(pq->tail==NULL)
        pq->head=pq->tail=newnode;
    }
    else
    {
        pq->tail->next=newnode;
        pq->tail=newnode;
    }
    pq->size++;
}

3.6出队列

要领: 找到原本头节点的下一个节点 更换一下新的头节点就好了,注意free就行

void QueuePop(Queue* pq)
{
    assert(pq);
    assert(pq->head!=NULL);

    Queue* tmp=pq->head->next;
    free(pq->head);
    pq->head=tmp;

    if(pq->head==NULL)
    {
        pq->tail=NULL;
    }
    pq->size--;
}

3.7计算队列大小

要领: 返回size的大小即可;

int QueueSize(Queue* pq)
{
    assert(pq);
    return pq->size;
}

3.8判断队列是否为空

要领: 其实本质就是看size是否为0;

bool QueueEmpty(Queue* pq)
{
    assert(pq);

    return pq->size==0;
}

3.9取对头元素

要领: 队列非空,取 head 出数据

QDatatype QueueFront(Queue* pq)
{
    assert(pq);
    assert(!QueueEmpty(pq));

    return pq->head->data;
}

3.10取队尾元素

要领: 队列非空,取 tail 处数据。

QDatatype QueueBack(Queue* pq)
{
    assert(pq);
    assert(!QueueEmpty(pq));

    return pq->tail->data;
}

四、队列的总代码

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>

typedef char QDatatype;

typedef struct QueueNode
{
    struct QueueNode* next;
    QDatatype data;
}QNode;

typedef struct Queue
{
    QNode* head;
    QNode* tail;
    int size;
}Queue;

void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
void QueuePush(Queue* pq,QDatatype x);
void QueuePop(Queue* pq);
int QueueSize(Queue* pq);
bool QueueEmpty(Queue* pq);
QDatatype QueueFront(Queue* pq);
QDatatype QueueBack(Queue* pq);

//--------------------------手动分割线---------------------------
//初始化
void QueueInit(Queue* pq)
{
    //暴力检查
    assert(pq);

    pq->head=pq->tail=NULL;
    pq->size=0;
}
//--------------------------手动分割线---------------------------
//销毁
void QueueDestroy(Queue* pq)
{
    assert(pq);

    Queue* cur=pq->head;
    while(cur)
    {
        Queue* tmp=cur->next;
        free(cur);
        cur=tmp;
    }
    pq->head=pq->tail=NULL;
    pq->size=0;
}
//--------------------------手动分割线---------------------------

void QueuePush(Queue* pq,QDatatype x)
{
    Queue* newnode=(Queue*)malloc(sizeof(Queue));
    if(newnode==NULL)
    {
        perror("malloc fail");
        return;
    }
    newnode->data=x;
    newnode->nxet=NULL;
    
    if(pq->head=NULL)
    {
        assert(pq->tail==NULL)
        pq->head=pq->tail=newnode;
    }
    else
    {
        pq->tail->next=newnode;
        pq->tail=newnode;
    }
    pq->size++;
}
//--------------------------手动分割线---------------------------

void QueuePop(Queue* pq)
{
    assert(pq);
    assert(pq->head!=NULL);

    Queue* tmp=pq->head->next;
    free(pq->head);
    pq->head=tmp;

    if(pq->head==NULL)
    {
        pq->tail=NULL;
    }
    pq->size--;
}
//--------------------------手动分割线---------------------------

int QueueSize(Queue* pq)
{
    assert(pq);
    return pq->size;
}
//--------------------------手动分割线---------------------------

bool QueueEmpty(Queue* pq)
{
    assert(pq);

    return pq->size==0;
}
//--------------------------手动分割线---------------------------

QDatatype QueueFront(Queue* pq)
{
    assert(pq);
    assert(!QueueEmpty(pq));

    return pq->head->data;
}
//--------------------------手动分割线---------------------------

QDatatype QueueBack(Queue* pq)
{
    assert(pq);
    assert(!QueueEmpty(pq));

    return pq->tail->data;
}

在这里插入图片描述
在这里插入图片描述

总结

  今天学习了单链表的知识,初次写数据结构的知识,给我的感觉就是,学三遍不如手敲代码一遍来的实在,所以数据结构的学习我将多画图,多敲代码来学习,希望大家吸取经验和我一起学习数据结构,为后面打比赛刷题打下坚实基础。

  我是夏目浅石,希望和你一起学习进步,刷题无数!!!希望各位大佬能一键三连支持一下博主,hhhh~我们下期见喽
在这里插入图片描述
如果无聊的话,就来逛逛我的博客栈吧stack-frame.cn

原创不易,还希望各位大佬支持一下 \textcolor{blue}{原创不易,还希望各位大佬支持一下} 原创不易,还希望各位大佬支持一下

👍 点赞,你的认可是我创作的动力! \textcolor{9c81c1}{点赞,你的认可是我创作的动力!} 点赞,你的认可是我创作的动力!

⭐️ 收藏,你的青睐是我努力的方向! \textcolor{ed7976}{收藏,你的青睐是我努力的方向!} 收藏,你的青睐是我努力的方向!

✏️ 评论,你的意见是我进步的财富! \textcolor{98c091}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!


http://www.kler.cn/a/2032.html

相关文章:

  • OpenHarmony-6.IPC/RPC组件
  • 深入了解Java在人工智能领域的最新应用
  • Elasticsearch:什么是提示工程 - prompt engineering?
  • ARP..
  • 游戏AI实现-寻路算法(A*)
  • Unbuntu下怎么生成SSL自签证书?
  • 【设计模式】UML、RUP、元素、关系、视图
  • 二分查找法
  • 经典七大比较排序算法 · 下 + 附计数和基数排序
  • 如何用matlab工具箱训练一个SOM神经网络
  • synchronized 加锁 this 和 class 的区别
  • QT | 编写一个简单的上位机
  • GEC6818开发板JPG图像显示,科大讯飞离线语音识别包Linux_aitalk_exp1227_1398d7c6运行demo程序,开发板实现录音
  • 思维导图模板怎么制作?提供几种思路
  • chatgpt3.5和chatgpt4的区别
  • GPT4论文翻译 by GPT4 and Human
  • 网络安全之防火墙
  • Vue2项目总结-电商后台管理系统
  • 软件测试拿了几个20K offer,分享一波面经
  • “工作三年,跳槽要求涨薪50%”,合理吗?
  • LeetCode:35. 搜索插入位置
  • 【洛谷刷题】蓝桥杯专题突破-深度优先搜索-dfs(4)
  • 100天精通Python(可视化篇)——第80天:matplotlib绘制不同种类炫酷柱状图代码实战(簇状、堆积、横向、百分比、3D柱状图)
  • python网上选课系统django-PyCharm
  • 新闻稿的写作格式
  • 【国产FPGA】国产FPGA搭建图像处理平台