• 【数据结构】队列详解


    Hello everybody!今天给大家讲讲队列的相关知识。队列,属于一种数据结构。从字面意思上理解,就像是排队一样,在食堂中,先排队的人自然就先买到饭。队列也是如此,先入队列的数据自然就先出队列。希望大家可以通过这篇文章解决自己心中的疑惑!那废话不多说,让我们开始叭!

                    ​​​​​​​        ​​​​​​​      

    1.队列的概念及结构

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

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

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

    2.队列的实现

    队列可以以数组和链表的结构实现,使用链表的结构实现更优,因为如果使用数组的结构,出队列是需要移动数据,时间复杂度是O(n),效率比较低。

    由于实现队列需要较长的代码,因此我们要像公司中做大型项目一样创建一个头文件:Queue.h和两个源文件:Queue.c Test.c。

    头文件中需要包含所需要的库文件,接口的声明,队列的声明。总之就是要我们清晰的看到队列的结构和功能。

    而源文件Queue.c需要实现在头文件中声明的接口。

    源文件Test.c用于测试队列的功能是否正常。

    当然源文件需要包含头文件,这样才能把它们关联起来。

    创建三个文件使得代码逻辑更加清晰,有利于后期代码的维护。

    2.1接口的声明&队列的声明

    这是队列的结构,结构体QNode是队列的链式结构,它可以存放当前结点的值和下一个结点的地址。但是当队列为空,插入第一个数据时,需要改变头指针。因此需要传递二级指针,这样显然是有些麻烦的。所以我们再创建一个结构体Queue,用于存放队列的头指针和尾指针,更方便入队和出队。size用来记录队列中的元素个数。

    以上是队列主要功能的接口,下面我们来逐个实现它们。

    2.2接口的实现及功能测试

    目前为止,我们已经实现了初始化和入队两个接口。下面测试一下它们的功能。

    通过调试,我们可以看到:初始化后,在队尾成功插入1和2。目前队列中有两个数值,接口功能正常。

    下面我们来实现一下其他的接口:

    这是队列剩下的接口,咱们也来测试一下。

    从测试结果来看:各个接口功能正常,销毁队列后,头指针和尾指针都被置为空指针,队列大小size为0。符合要求。

    3.代码

    为了方便大家更好的学习,队列的代码我也给出来!

    1. #pragma once
    2. #include
    3. #include
    4. #include
    5. #include
    6. typedef int QDataType;
    7. typedef struct QueueNode {
    8. QDataType val;
    9. struct QueueNode* next;
    10. }QNode;
    11. typedef struct Queue {
    12. QNode* phead;
    13. QNode* ptail;
    14. int size;
    15. }Queue;
    16. void QueueInit(Queue* pq);//初始化
    17. void QueuePush(Queue* pq, QDataType x);//入队
    18. void QueuePop(Queue* pq);//出队
    19. void QueueDestroy(Queue* pq);//销毁
    20. QDataType QueueFront(Queue* pq);//返回队头的值
    21. QDataType QueueBack(Queue* pq);//返回队尾的值
    22. bool QueueEmpty(Queue* pq);//判断队列是否为空
    23. int QueueSize(Queue* pq);//返回队列的数据个数
    1. #include "Queue.h"
    2. void QueueInit(Queue* pq) {
    3. assert(pq);//检验pq是否为空指针
    4. pq->phead = pq->ptail = NULL;
    5. pq->size = 0;
    6. }
    7. void QueuePush(Queue* pq, QDataType x) {
    8. assert(pq);
    9. QNode* newnode = (QNode*)malloc(sizeof(QNode));//动态开辟一个新结点
    10. if (newnode == NULL) {//若开辟失败,终止程序
    11. perror("malloc fail");
    12. exit(-1);
    13. }
    14. newnode->val = x;
    15. newnode->next = NULL;
    16. if (pq->phead == NULL) {//如果队列中没有结点,则将新结点赋值给头指针和尾指针
    17. pq->phead = pq->ptail = newnode;
    18. }
    19. else {
    20. pq->ptail->next = newnode;//有结点的话,将新结点赋值给尾指针
    21. pq->ptail = newnode;
    22. }
    23. pq->size++;
    24. }
    25. void QueuePop(Queue* pq) {
    26. assert(pq);
    27. assert(pq->phead);//队列不能为空
    28. QNode* next = pq->phead->next;//记录头结点的下一个结点
    29. free(pq->phead);
    30. pq->phead = next;
    31. if (pq->phead == NULL) {//当phead为NULL时,ptail没有变化。但ptail指向的空间已经还给操作系统,此时ptail就是野指针,必须处理掉!
    32. pq->ptail = NULL;
    33. }
    34. pq->size--;
    35. }
    36. QDataType QueueFront(Queue* pq) {
    37. assert(pq);
    38. assert(pq->phead);
    39. return pq->phead->val;
    40. }
    41. QDataType QueueBack(Queue* pq) {
    42. assert(pq);
    43. assert(pq->ptail);
    44. return pq->ptail->val;
    45. }
    46. bool QueueEmpty(Queue* pq) {
    47. assert(pq);
    48. return pq->phead == NULL;
    49. }
    50. int QueueSize(Queue* pq) {
    51. assert(pq);
    52. return pq->size;
    53. }
    54. void QueueDestroy(Queue* pq) {
    55. assert(pq);
    56. while (pq->phead) {
    57. QNode* next = pq->phead->next;
    58. free(pq->phead);
    59. pq->phead = next;
    60. }
    61. pq->phead = pq->ptail = NULL;
    62. pq->size = 0;
    63. }
    1. #include "Queue.h"
    2. int main() {
    3. Queue pq;
    4. QueueInit(&pq);
    5. QueuePush(&pq, 1);
    6. QueuePush(&pq, 2);
    7. QueuePush(&pq, 3);
    8. QueuePush(&pq, 4);
    9. printf("%d\n", QueueBack(&pq));
    10. printf("%d\n", QueueSize(&pq));
    11. while (!QueueEmpty(&pq)) {
    12. printf("%d", QueueFront(&pq));
    13. QueuePop(&pq);
    14. }
    15. QueueDestroy(&pq);
    16. return 0;
    17. }

    4.结语

    好啦,关于队列的讨论就到这里叭。不知道大家有没有收获呢?如果有疑问,可以发在评论区。

    最后,希望宝子们每天都有所进步,成为自己想成为的人,做自己想做的事!\(0^◇^0)/

  • 相关阅读:
    LrC 13 & ACR 16:点颜色
    JavaWeb_LeadNews_Day11-KafkaStream实现实时计算文章分数
    java计算机毕业设计医院挂号系统源程序+mysql+系统+lw文档+远程调试
    pytest
    python - 内存池的机制
    用HTML+CSS做一个漂亮简单的花店网页【免费的学生网页设计成品】
    Linux服务器配置信息查询命令
    OSI与TCP/IP与的体系结构的比较
    上海亚商投顾:沪指震荡反弹 汽车产业链全天强势
    元数据性能大比拼:HDFS vs S3 vs JuiceFS
  • 原文地址:https://blog.csdn.net/c565114/article/details/134492104