码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 数据结构之——队列详解 ( 1 )


    目录

    前言     

    一.队列

    2.1队列的概念及结构

            1.定义:

            2.理解

    二.队列的实现

    1. 队列的数据结构

    2.队列的初始化函数 

    3.释放空间

    4.入队——插入元素(从队尾处)

            图解:

             函数代码:

    5.检查队列是否为空

    6.出队——删除元素(从队头处)

            图解:

            函数代码:

    7.返回队列的队头元素值

    8.返回队列的队尾元素值 

    9.求队列的长度


    前言     

            栈和队列都是两个特殊类型的线性表,之前讲过了关于栈型线性表的特点和功能实现,博客如下: 数据结构之——栈的操作讲解与功能实现

            感兴趣的伙伴们可以去看看,接下来就需要来了解了解队列了。

    一.队列

    2.1队列的概念及结构

            1.定义:

            只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out)的原则。

            入队列:进行插入操作的一端称为队尾。

            出队列:进行删除操作的一端称为队。

            2.理解

            队列名副其实就是排队,就好比在医院看病,排了一字长龙,那么先挂号的病患就有优先看病的权力,后来排上队的人就得慢慢等了,这与栈的特征是完全相反的!

            队列既然也是线性表,那么就具有两种实现方式:顺序存储类型和链式存储类型。

            顺序存储就是用数组实现,比如有一个n个元素的队列,数组下标0的一端是队头,入队操作就是通过数组下标一个个顺序追加,不需要移动元素,但是如果删除队头元素,后面的所有元素就要往前移动一次,若删除多个头元素,那么就要移动n次,所对应的时间复杂度就是O(n),性能和效率自然低下;而且在删除元素时,会造成空间的丢失,如下图:

            若使用链表实现,链式存储的头部删除极为简单方便,而且链表中也有单链表形式和双向链表形式,本人认为使用单链表好一些,毕竟队列的实现很简单,双向链表有大材小用,杀鸡焉用牛刀的做法了。

            对比来看,链式队列比顺序队列的好处就在于,链式队列节省空间。

    二.队列的实现

     

    1. 队列的数据结构

    1. typedef int QUEUENode;
    2. //单向链式结构体数据类型
    3. typedef struct QuNode {
    4. QUEUENode data;
    5. struct QuNode* next;
    6. }QN;
    7. //封装链式结构体QN的一个结构体队列
    8. typedef struct Queue {
    9. QN* head;//队列头指针
    10. QN* tail;//队列尾指针
    11. }Queue;

    2.队列的初始化函数 

    1. //初始化
    2. void QueueInit(Queue* pq) {
    3. assert(pq);
    4. pq->head = pq->tail = NULL;
    5. }

    3.释放空间

    1. //释放空间
    2. void QueueDestory(Queue* pq) {
    3. assert(pq);
    4. QN* cur = pq->head;
    5. while (cur) {
    6. QN* del = cur;
    7. cur = cur->next;
    8. free(del);
    9. del = NULL;
    10. }
    11. pq->head = pq->tail = NULL;
    12. }

    4.入队——插入元素(从队尾处)

    图解:

     函数代码:

    1. //入队
    2. void QueuePush(Queue* pq, QUEUENode x) {
    3. assert(pq);
    4. //开辟节点
    5. QN* newnode = (QN*)malloc(sizeof(QN));
    6. //若开辟失败
    7. if (newnode == NULL) {
    8. perror("malloc fail");
    9. exit(-1);
    10. }
    11. //开辟成功:
    12. else {
    13. newnode->data = x;
    14. newnode->next = NULL;
    15. }
    16. //若队列为空
    17. if (pq->tail == NULL) {
    18. pq->head = pq->tail = newnode;
    19. }
    20. //若队列不为空
    21. else {
    22. pq->tail->next = newnode;
    23. pq->tail = newnode;
    24. }
    25. }

    5.检查队列是否为空

    在删除元素时,需要进行检查队列中是否有元素,若有元素,则断言false,通过该语句照常进行删除;若没有元素,则断言true 确认为空,程序报错!

    1. //暴力检查
    2. bool QueueEmpty(Queue* pq) {
    3. assert(pq);
    4. return pq->head == NULL && pq->tail == NULL;
    5. }

    注:C语言中没有bool类型,所以需要用到头文件#include即可使用

    6.出队——删除元素(从队头处)

    图解:

    函数代码:

    1. //出队
    2. void QueuePop(Queue* pq) {
    3. assert(pq);
    4. //判断队列是否为空
    5. assert(!QueueEmpty(pq));
    6. //表明队列不为空,可以正常删除元素
    7. //情况1:
    8. if (pq->head->next == NULL) {
    9. free(pq->head);
    10. pq->head = pq->tail = NULL;
    11. }
    12. //情况2:
    13. else {
    14. QN* del = pq->head;
    15. pq->head = pq->head->next;
    16. free(del);
    17. del = NULL;
    18. }
    19. }

    7.返回队列的队头元素值

    1. //返回队头元素
    2. QUEUENode Queuehead(Queue* pq) {
    3. assert(pq);
    4. assert(!QueueEmpty(pq));
    5. return pq->head->data;
    6. }

    该函数的作用就是方便我们去打印输出队头元素的值

    8.返回队列的队尾元素值 

    1. //返回队尾元素
    2. QUEUENode Queuetail(Queue* pq) {
    3. assert(pq);
    4. assert(!QueueEmpty(pq));
    5. return pq->tail->data;
    6. }

    该函数的作用就是方便我们去打印输出队尾元素的值

    9.求队列的长度

    1. //队列长度
    2. int QueueSize(Queue* pq) {
    3. assert(pq);
    4. int n = 0;
    5. QN* cur = pq->head;
    6. while (cur) {
    7. ++n;
    8. cur = cur->next;
    9. }
    10. return n;
    11. }

    测试: 

     

    记得测试完需要使用QueueDestory释放空间函数,否则会造成内存泄漏!!! 

    注:队列的增删方式只能为:头部删除元素,尾部插入元素

  • 相关阅读:
    LED显示屏像素技术
    计算机毕业设计选题推荐-社区团购管理系统-Python项目实战
    虹科新闻 | 虹科电子与 Mend 正式建立合作伙伴关系
    Python 自动化详解(pyautogui)
    我的Vim学习笔记(不定期更新)
    二十、处理器调度(RR时间片轮转,MLFQ多级反馈队列,CFS完全公平调度器,优先级翻转;多处理器调度)
    【CSS入门】第一课 - CSS内容都可以写在哪里?
    【计算机毕业设计】211校园约拍微信小程序
    uniapp开发小程序-pc端小程序下载文件
    猿创征文|paddle 39 基于Paddle Inference在win环境用Cmake编译部署resnet50并加载图像测试
  • 原文地址:https://blog.csdn.net/weixin_69283129/article/details/126626426
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号