• 带你深入了解队列(c/cpp双版本模拟实现)


    目录

    一.队列的概念及结构

    二.队列的实现

    2.1队列的结构

    2.2初始化队列

    2.3队尾入队列 

    2.4队头出队列 

    2.5获取队列头部元素 

    2.6获取队列队尾元素

    2.7获取队列中有效元素个数 

    2.8检测队列是否为空

    2.9销毁队列 

    三.C++ 版本模拟实现队列


    一.队列的概念及结构

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

    二.队列的实现

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

    2.1队列的结构

    首先,先建立一个单链表,用来存储数据和链接结构

    然后建立队列,队列有俩个节点,一个指向队列的开始,一个指向结尾

    size 用于存储队列长度

    1. // 链式结构:表示队列
    2. typedef struct QListNode
    3. {
    4. struct QListNode* _pNext;
    5. QDataType _data;
    6. }QNode;
    7. // 队列的结构
    8. typedef struct Queue
    9. {
    10. QNode* _front;
    11. QNode* _rear;
    12. int size;
    13. }Queue;

    2.2初始化队列

    队列的初始化,把队列的头尾都指向空,size设为0

    1. void QueueInit(Queue* q)
    2. {
    3. q->front = NULL;
    4. q->rear = NULL;
    5. q->size = 0;
    6. }

    2.3队尾入队列 

    1.首先,malloc一个节点cur

    2.判断malloc是否开辟成功

    3.给创建成功的节点进行赋值

    4.判断如果队列为空,直接插入节点即可(使队列的头尾都指向这个节点)

    5.如果不为空,使队列的尾的下一个位置指向新创建的节点在然后队列的尾指向这个节点

    6.最后,数据加一size++

    1. void QueuePush(Queue* q, QDataType data)
    2. {
    3. QNode* cur = (QNode*)malloc(sizeof(QNode));
    4. if (cur == NULL)
    5. {
    6. perror("malloc ");
    7. exit(-1);
    8. }
    9. cur->data = data;
    10. cur->next = NULL;
    11. if (q->rear == NULL)
    12. {
    13. q->front = q->rear = cur;
    14. }
    15. else
    16. {
    17. q->rear->next = cur;
    18. q->rear = cur;
    19. }
    20. q->size++;
    21. }

    2.4队头出队列 

    1.先判断队列是否只有为空,如果是,退出

    2.如果队列只有一个数据,直接对队列进行销毁即可

    3.如果队列有多个数据,新建一个节点cur等于队列“头”的下一个地址,然后释放掉队头,再把队头指向cur(以前对头的下一个地址),使得第二个数据成为队头

    4.最后,数据减一size--

    1. void QueuePop(Queue* q)
    2. {
    3. if(q->front==NULL)
    4. {
    5. exit(-1);
    6. }
    7. if (q->front->next == NULL)
    8. {
    9. free(q->front);
    10. q->front = q->rear = NULL;
    11. }
    12. else
    13. {
    14. QNode* cur = q->front->next;
    15. free(q->front);
    16. q->front = cur;
    17. }
    18. q->size--;
    19. }

    2.5获取队列头部元素 

    直接取头指向的数据即可

    1. QDataType QueueFront(Queue* q)
    2. {
    3. return q->front->data;
    4. }

    2.6获取队列队尾元素

    直接取队列尾指向的元素即可

    1. QDataType QueueBack(Queue* q)
    2. {
    3. return q->rear->data;
    4. }

    2.7获取队列中有效元素个数 

    直接返回队列的size

    1. int QueueSize(Queue* q)
    2. {
    3. return q->size;
    4. }

    2.8检测队列是否为空

    检测队列是否为空,如果为空返回非零结果,如果非空返回0 

    1. bool QueueEmpty(Queue* q)
    2. {
    3. return q->front == NULL && q->rear == NULL;
    4. }

    2.9销毁队列 

    1.采用while循环依次把队列中的节点全部释放

    2.使队列头尾指向空,并且size置为0

    1. void QueueDestroy(Queue* q)
    2. {
    3. QNode* cur = q->front;
    4. while (cur)
    5. {
    6. QNode* del = cur;
    7. cur = cur->next;
    8. free(del);
    9. }
    10. q->front = NULL;
    11. q->rear = NULL;
    12. q->size = 0;
    13. }

    三.C++ 版本模拟实现队列
     

         考虑到学校有好多老师上课,虽然说得是用c语言实现,却用cpp进行操作,现在给大家更新cpp版本的队列的模拟实现,cpp版本的扩容使用的new,函数参数使用的&,可能有同学对指针使用不太熟悉,所以我们同意用&(引用)来实现,方便大家的理解,就不再详细的进行说明了,思路跟c语言实现的一样,只是c和cpp的语言差距有所不同。

    1. #include<iostream>
    2. #include<assert.h>
    3. using namespace std;
    4. typedef int QDataType;
    5. typedef struct QListNode
    6. {
    7. struct QListNode* next;
    8. QDataType data;
    9. }QNode;
    10. // 队列的结构
    11. typedef struct Queue
    12. {
    13. QNode* front;
    14. QNode* rear;
    15. int size;
    16. }Queue;
    17. // 初始化队列
    18. void QueueInit(Queue& q)
    19. {
    20. q.front = NULL;
    21. q.rear = NULL;
    22. q.size = 0;
    23. }
    24. // 队尾入队列
    25. void QueuePush(Queue& q, QDataType data)
    26. {
    27. QNode* cur = new QNode[sizeof(QNode)];
    28. if (cur == NULL)
    29. {
    30. perror("malloc ");
    31. exit(-1);
    32. }
    33. cur->data = data;
    34. cur->next = NULL;
    35. if (q.rear == NULL)
    36. {
    37. q.front = q.rear = cur;
    38. }
    39. else
    40. {
    41. q.rear->next = cur;
    42. q.rear = cur;
    43. }
    44. q.size++;
    45. }
    46. // 队头出队列
    47. void QueuePop(Queue& q)
    48. {
    49. if (q.front->next == NULL)
    50. {
    51. delete q.front;
    52. q.front = q.rear = NULL;
    53. }
    54. else
    55. {
    56. QNode* cur = q.front->next;
    57. delete q.front;
    58. q.front = cur;
    59. }
    60. q.size--;
    61. }
    62. // 获取队列头部元素
    63. QDataType QueueFront(const Queue& q)
    64. {
    65. return q.front->data;
    66. }
    67. // 获取队列队尾元素
    68. QDataType QueueBack(const Queue& q)
    69. {
    70. return q.rear->data;
    71. }
    72. // 获取队列中有效元素个数
    73. int QueueSize(const Queue& q)
    74. {
    75. return q.size;
    76. }
    77. // 检测队列是否为空,如果为空返回非零结果,如果非空返回0
    78. bool QueueEmpty(const Queue& q)
    79. {
    80. return q.front == NULL && q.rear == NULL;
    81. }
    82. // 销毁队列
    83. void QueueDestroy(Queue& q)
    84. {
    85. QNode* cur = q.front;
    86. while (cur)
    87. {
    88. QNode* del = cur;
    89. cur = cur->next;
    90. free(del);
    91. }
    92. q.front = NULL;
    93. q.rear = NULL;
    94. q.size = 0;
    95. }
    96. int main()
    97. {
    98. Queue q;
    99. QueueInit(q);
    100. QueuePush(q, 1);
    101. QueuePush(q, 2);
    102. QueuePush(q, 3);
    103. for (int i = 0;i < 3;i++)
    104. {
    105. cout << QueueFront(q) << endl;
    106. QueuePop(q);
    107. }
    108. printf("%d", !QueueEmpty(q));
    109. QueueDestroy(q);
    110. return 0;
    111. }

  • 相关阅读:
    一比一还原axios源码(六)—— 配置化
    JAVA春运出行铁路路线规划推荐系统计算机毕业设计Mybatis+系统+数据库+调试部署
    14:00面试,14:06就出来了,问的问题有点变态。。。
    Python文件操作详细介绍(打开、读取、写入、上下文管理器、关闭、异常处理;文件模式、编码、路径、读写位置、复制、移动、删除)
    算法通过村第十八关-回溯|白银笔记|经典问题
    Stream流处理快速上手最佳实践 | 京东物流技术团队
    数据结构 图
    (热门推荐)天津web前端培训班 Web前端学习顺序
    linux SHELL技巧
    力扣经典题目之->移除值为val元素的讲解,的实现与讲解
  • 原文地址:https://blog.csdn.net/weixin_55582891/article/details/134075225