当前位置:   article > 正文

队列及其实现_队列的实现csdn

队列的实现csdn

目录

一:队列

1.队列的概念及结构

2.队列的实现

<1>.初始化队列

<2>.队尾入队列

<3>.队头出队列

<4>.获取队列头部元素

<5>.获取队列队尾元素

<6>.获取队列中有效元素个数 

<7>.销毁队列 

二:完整代码


一:队列

1.队列的概念及结构


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

2.队列的实现


队列的实现可以通过数组实现,也可以通过链表实现,在此处,如果使用数组实现的话,出的队列在数组头上出数据,效率很低,在此处,我们选择泳联表来实现。


 需要创建链式结构和队列的结构:

 typedef int QDataType;

 //链式结构:表示队列 
typedef struct QListNode
{
    struct QListNode* _next;
    QDataType _data;
}QNode;

// 队列的结构 
typedef struct Queue
{
    QNode* _front;//队头
    QNode* _rear;//队尾
    int size;
}Queue;                                                                                                                       

<1>.初始化队列


void QueueInit(Queue* q);


令队头,队尾为空,队列中的元素个数为 0 .

代码为:

  1. // 初始化队列
  2. void QueueInit(Queue* q)
  3. {
  4. assert(q);
  5. q-> _rear = NULL;
  6. q-> _front = NULL;
  7. q->size = 0;
  8. }

<2>.队尾入队列


 void QueuePush(Queue* q, QDataType data);


 在队列尾部,入队列,本质上是对链表进行操作,需要开辟一个一个新的节点,将其于队列中的内容链接起来,最后对元素总数进行 ++ 操作。

 画图分析如下:

 代码为:

  1. // 队尾入队列
  2. void QueuePush(Queue* q, QDataType data)
  3. {
  4. assert(q);
  5. //插入数据 --- 链表 --- 开辟新的节点(结构体)
  6. QNode* newnode = (QNode*)malloc(sizeof(QNode));
  7. if (newnode == NULL)
  8. {
  9. perror("malloc fail");
  10. return;
  11. }
  12. newnode->_data = data;
  13. newnode->_next = NULL;
  14. //判断队列中是否有元素
  15. if (q->_rear == NULL)
  16. {
  17. assert(q->_front == NULL);
  18. //相当于对链表进行头插
  19. q->_front = q->_rear = newnode;
  20. }
  21. else
  22. {
  23. //相当于在队列的结尾,插入一个结构体
  24. q->_rear->_next = newnode;
  25. q->_rear = newnode;
  26. }
  27. q->size++;
  28. }

<3>.队头出队列


 void QueuePop(Queue* q);


在出队列时,我们需要考虑队列中是否有元素,若队列为空,则无法进行出队列操作 --- 即需要对链表进行判空。若队列中有元素,则需要考虑队列中有几个节点:若队列中只有一个节点,进行出队列操作一次后,队列即为空。若队列中有多个节点时,可以开辟一个新的节点用于记录头节点的下一个位置,然后释放头节点,将开辟的新节点看作队列的队头。

画图分析:

 

 代码为:

  1. // 检测队列是否为空,如果为空返回零结果
  2. int QueueEmpty(Queue* q)
  3. {
  4. assert(q);
  5. return q->_rear == NULL;
  6. }
  7. // 队头出队列
  8. void QueuePop(Queue* q)
  9. {
  10. assert(q);
  11. //需要判断队列中是否有元素 --- 若队列为空,则无法进行出队列
  12. assert(!QueneEmpty(q));
  13. //判断有几个节点 --- 一个节点 --- 多个节点
  14. if (q->_front->_next == NULL)
  15. {
  16. free(q->_front);
  17. q->_front = NULL;
  18. q->_rear = NULL;
  19. }
  20. else
  21. {
  22. QNode* next = q->_front->_next;
  23. free(q->_front);
  24. q->_front = next;
  25. }
  26. q->size--;
  27. }

<4>.获取队列头部元素


 QDataType QueueFront(Queue* q);


获取队列头部元素时,需要判断队列是否为空,若队列为空,则无队列头部元素。

获取头部元素 q->_front_data

代码为:

  1. // 检测队列是否为空,如果为空返回零结果
  2. int QueueEmpty(Queue* q)
  3. {
  4. assert(q);
  5. return q->_rear == NULL;
  6. }
  7. // 获取队列头部元素
  8. QDataType QueueFront(Queue* q)
  9. {
  10. assert(q);
  11. //需要判断队列中是否有元素 --- 若队列为空,则无队列头部元素
  12. assert(!QueneEmpty(q));
  13. return q->_front->_data;
  14. }

<5>.获取队列队尾元素


 QDataType QueueBack(Queue* q);


获取队列队尾元素时,需要判断队列中是否有元素,即需要判断队列是否为空。

获取尾部元素 q->_rear->_data

代码为:

  1. // 检测队列是否为空,如果为空返回零结果
  2. int QueueEmpty(Queue* q)
  3. {
  4. assert(q);
  5. return q->_rear == NULL;
  6. }
  7. // 获取队列队尾元素
  8. QDataType QueueBack(Queue* q)
  9. {
  10. assert(q);
  11. //需要判断队列中是否有元素 --- 若队列为空,则无队列尾q元素
  12. assert(!QueneEmpty(q));
  13. return q->_rear->_data;
  14. }

<6>.获取队列中有效元素个数 


int QueueSize(Queue* q);


我们在入队列时,进行了q->_size++ , 出队列时,进行 q->_size-- 。

即 q->_size 即为队列中有效元素的个数。

代码为:

  1. // 获取队列中有效元素个数
  2. int QueueSize(Queue* q)
  3. {
  4. assert(q);
  5. return q->size;
  6. }

<7>.销毁队列 


void QueueDestroy(Queue* q);


队列内部建立的是链表结构,而链表在释放的时候需要一个一个销毁,在此时,我们需要建立一个结构体指针指向队列的头部(QNode* cur = q->_front),然后一个一个地释放节点,循环条件更替条件为:cur = cur->_next , 当 cur 为空时,循环结束。然后将队列的内部元素置为空或者0。

画图分析:

 代码为:

  1. // 销毁队列
  2. void QueueDestroy(Queue* q)
  3. {
  4. assert(q);
  5. //链表需要一个一个销毁 -- 修改的为链表
  6. QNode* cur = q->_front;
  7. while (cur)
  8. {
  9. QNode* next = cur->_next;
  10. free(cur);
  11. cur = next;
  12. }
  13. q->size = 0;
  14. q->_front = NULL;
  15. q->_rear = NULL;
  16. }

二:完整代码

 queue.h

  1. #pragma once
  2. #include<stdio.h>
  3. #include<assert.h>
  4. #include<stdlib.h>
  5. typedef int QDataType;
  6. //链式结构:表示队列
  7. typedef struct QListNode
  8. {
  9. struct QListNode* _next;
  10. QDataType _data;
  11. }QNode;
  12. // 队列的结构
  13. typedef struct Queue
  14. {
  15. QNode* _front;//队头
  16. QNode* _rear;//队尾
  17. int size;
  18. }Queue;
  19. //初始化队列
  20. void QueueInit(Queue* q);
  21. // 队尾入队列
  22. void QueuePush(Queue* q, QDataType data);
  23. // 队头出队列
  24. void QueuePop(Queue* q);
  25. // 获取队列头部元素
  26. QDataType QueueFront(Queue* q);
  27. // 获取队列队尾元素
  28. QDataType QueueBack(Queue* q);
  29. // 获取队列中有效元素个数
  30. int QueueSize(Queue* q);
  31. // 检测队列是否为空,如果为空返回非零结果,如果非空返回0
  32. int QueueEmpty(Queue* q);
  33. // 销毁队列
  34. void QueueDestroy(Queue* q);

queue.c

  1. #include"quene.h"
  2. // 初始化队列
  3. void QueueInit(Queue* q)
  4. {
  5. assert(q);
  6. q-> _rear = NULL;
  7. q-> _front = NULL;
  8. q->size = 0;
  9. }
  10. // 队尾入队列
  11. void QueuePush(Queue* q, QDataType data)
  12. {
  13. assert(q);
  14. //插入数据 --- 链表 --- 开辟新的节点(结构体)
  15. QNode* newnode = (QNode*)malloc(sizeof(QNode));
  16. if (newnode == NULL)
  17. {
  18. perror("malloc fail");
  19. return;
  20. }
  21. newnode->_data = data;
  22. newnode->_next = NULL;
  23. //判断队列中是否有元素
  24. if (q->_rear == NULL)
  25. {
  26. assert(q->_front == NULL);
  27. //相当于对链表进行头插
  28. q->_front = q->_rear = newnode;
  29. }
  30. else
  31. {
  32. //相当于在队列的结尾,插入一个结构体
  33. q->_rear->_next = newnode;
  34. q->_rear = newnode;
  35. }
  36. q->size++;
  37. }
  38. // 检测队列是否为空,如果为空返回零结果
  39. int QueueEmpty(Queue* q)
  40. {
  41. assert(q);
  42. return q->_rear == NULL;
  43. }
  44. // 队头出队列
  45. void QueuePop(Queue* q)
  46. {
  47. assert(q);
  48. //需要判断队列中是否有元素 --- 若队列为空,则无法进行出队列
  49. assert(!QueneEmpty(q));
  50. //判断有几个节点 --- 一个节点 --- 多个节点
  51. if (q->_front->_next == NULL)
  52. {
  53. free(q->_front);
  54. q->_front = NULL;
  55. q->_rear = NULL;
  56. }
  57. else
  58. {
  59. QNode* next = q->_front->_next;
  60. free(q->_front);
  61. q->_front = next;
  62. }
  63. q->size--;
  64. }
  65. // 获取队列头部元素
  66. QDataType QueueFront(Queue* q)
  67. {
  68. assert(q);
  69. //需要判断队列中是否有元素 --- 若队列为空,则无队列头部元素
  70. assert(!QueneEmpty(q));
  71. return q->_front->_data;
  72. }
  73. // 获取队列队尾元素
  74. QDataType QueueBack(Queue* q)
  75. {
  76. assert(q);
  77. //需要判断队列中是否有元素 --- 若队列为空,则无队列尾q元素
  78. assert(!QueneEmpty(q));
  79. return q->_rear->_data;
  80. }
  81. // 获取队列中有效元素个数
  82. int QueueSize(Queue* q)
  83. {
  84. assert(q);
  85. return q->size;
  86. }
  87. // 销毁队列
  88. void QueueDestroy(Queue* q)
  89. {
  90. assert(q);
  91. //链表需要一个一个销毁 -- 修改的为链表
  92. QNode* cur = q->_front;
  93. while (cur)
  94. {
  95. QNode* next = cur->_next;
  96. free(cur);
  97. cur = next;
  98. }
  99. q->size = 0;
  100. q->_front = NULL;
  101. q->_rear = NULL;
  102. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/553240
推荐阅读
相关标签
  

闽ICP备14008679号