• I 用c I 实现队列


    目录

    一、队列的性质:

    二、队列的结构:

    三、代码实现

    头文件:

    功能函数:


    一、队列的性质:

           上次我们学习栈,了解到栈储存释放数据的方式是:先进后出

           而队列与其相反,队列是:先进先出,后进后出。

    二、队列的结构:

           多个链表节点 + 头尾指针   (链表式队列)

           链表节点负责存储数据;头节点 负责定位先进的起始数据,方便先出;

           尾节点负责记录尾部数据,方便确定队列当前状态。

           

    三、代码实现

    头文件:

    这里方便统一调用,将头尾指针定义成一个结构体 。 

    1. #include<stdio.h>
    2. #include<stdlib.h>
    3. #include<assert.h>
    4. #include<stdbool.h>
    5. typedef int Quetype; //定义队列的数据类型
    6. typedef struct QueNode //定义数据节点
    7. {
    8. struct QueNode* Next;
    9. Quetype data;
    10. }QueNode;
    11. typedef struct Quetail
    12. {
    13. struct QueNode* head; //定义头尾指针
    14. struct QueNode* tail;
    15. }Quetail;
    16. void Que_Init(Quetail* pq); //队列的初始化
    17. void Que_Destory(Quetail* pq); //队列的销毁
    18. void Que_push(Quetail* pq ,Quetype data); //插入数据
    19. void Que_pop(Quetail* pq); //删除数据
    20. bool Que_Empty(Quetail* pq); //判断队列是否为空
    21. int Que_size(Quetail* pq); //统计队列长度
    22. int Que_front(Quetail* pq); //查找队列的头部数据

    功能函数:

    1.队列的初始化:

    将头尾指针置为NULL 方便后续使用。

    1. void Que_Init(Quetail* pq) //队列的初始化
    2. {
    3. assert(pq);
    4. pq->head = pq->tail = NULL;
    5. }

    2.插入数据:

    创建链表节点 >> 导入数据 >> 头部指针指向头节点 >> 尾部指针指向尾节点 

    1. //插入数据
    2. void Que_push(Quetail* pq,Quetype data)
    3. {
    4. assert(pq);
    5. QueNode* NewNode = (QueNode*)malloc(sizeof(QueNode));//创建节点
    6. if (NewNode == NULL)
    7. {
    8. printf("Que_push->malloc");
    9. exit(-1);
    10. }
    11. NewNode->Next = NULL;
    12. NewNode->data = data;
    13. if (pq->head == NULL) //判断是否创建为头节点
    14. {
    15. pq->head = NewNode; //更新头指针
    16. }
    17. else
    18. {
    19. pq->tail->Next = NewNode; //不为头节点,就正常链接在尾节点后
    20. }
    21. pq->tail = NewNode; //更新尾指针
    22. }

    3.删除数据:

      记录头节点的下一个位置 >> 判断是否为最后的数据 >> 更新头指针

      细节点:如果队列中还剩多个节点时,删除头节点后,尾指针始终指向尾节点,不需要改动;

                   但是如果只剩一个数据节点的话,删除后需要将尾指针置空。

     

    1. //删除数据
    2. void Que_pop(Quetail* pq)
    3. {
    4. assert(pq);
    5. assert(!Que_Empty(pq)); //判断队列是否为空
    6. QueNode* Next = pq->head->Next; //记录删除数据的
    7. if (pq->head == pq->tail) //判断是否是最后的数据
    8. {
    9. free(pq->head);
    10. pq->tail = NULL; //更新尾指针
    11. }
    12. else
    13. {
    14. free(pq->head);
    15. }
    16. pq->head = Next; //更新头指针
    17. }

    4.判断列表是否为空:

    用bool 作为返回类型

     

    1. //判断队列是否为空
    2. bool Que_Empty(Quetail* pq)
    3. {
    4. assert(pq);
    5. return pq->head == NULL;
    6. }

    5.查找队列的头部数据:

    判断队列是否为空 >> 返回头部数据

    1. //查找队列的头部数据
    2. Quetype Que_front(Quetail* pq)
    3. {
    4. assert(pq);
    5. assert(!Que_Empty(pq)); //判断队列是否为空
    6. return pq->head->data; //返回头部数据
    7. }

    6. 计队列的长度:

    就是统计有多少个链表节点

    1. int Que_size(Quetail* pq)
    2. {
    3. assert(pq);
    4. int size;
    5. QueNode* pphead = pq->head;
    6. for (size = 0; pphead; pphead = pphead->Next, size++);
    7. return size;
    8. }

    7.队列的销毁:

      依次删除数据 >> 将申请空间释放

      细节点:这里可以进行复用:判断队列是否为空 、 删除数据

    1. void Que_Destory(Quetail* pq)
    2. {
    3. for (; !Que_Empty(pq); ) //判断队列是否为空
    4. {
    5. Que_pop(pq); //删除数据
    6. }
    7. }

     感谢各位大佬的支持!!!

     

     

     

     

     

     

     

     

          

  • 相关阅读:
    失眠睡不着如何调理
    android 存储新特性
    无线通讯技术助力汽车玻璃厂完成智能化转型升级
    实现游戏中的轮廓描边
    MySQL数据库主从复制
    应用程序生成器:App Builder 2023
    std::ofstream 写本地音频
    深度学习——模型选择、欠拟合和过拟合
    代码随想录二刷day29
    数据安全服务是什么意思?
  • 原文地址:https://blog.csdn.net/MT_125/article/details/125592627