当前位置:   article > 正文

[ 数据结构-C实现] 队列 Queue_queue队列

queue队列

目录

1.队列

1.1队列的概念及结构

2.队列的实现

2.1接口

3.接口的实现

3.1初始化

3.2销毁

分析:

 3.3入队

分析:

3.4出队

分析:

 3.5判断是否为空

3.6队列的大小

3.7返回头结点的元素Data

3.8返回尾结点的元素Data

4.完整代码

5.测试

测试结果:


1.队列

1.1队列的概念及结构

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

 

2.队列的实现

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

2.1接口

  1. //初始化
  2. void QueueInit(Queue* pq);
  3. //销毁
  4. void QueueDestory(Queue* pq);
  5. //入队
  6. void QueuePush(Queue* pq, QDataType x);
  7. //出队
  8. void QueuePop(Queue* pq);
  9. //判断是否为空
  10. bool QueueEmpty(Queue* pq);
  11. //队的大小
  12. size_t QueueSize(Queue* pq);
  13. QDataType QueueFront(Queue* pq);
  14. QDataType QueueBack(Queue* pq);

3.接口的实现

3.1初始化

初始化只需要让pq->head和pq->tail为NULL即可。

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

3.2销毁

  1. //销毁
  2. void QueueDestory(Queue* pq)
  3. {
  4. assert(pq);
  5. QNode* cur = pq->head;
  6. while (cur)
  7. {
  8. QNode* next = cur->next;
  9. free(cur);
  10. cur = next;
  11. }
  12. pq->head = pq->tail = NULL;
  13. }

分析:

我们需要创建一个cur指针保存head的地址,以及一个next指针保存cur的next地址

过程:

1、我们free(cur),再让cur走到next位置即可开始循环销毁。

2、循环结束的条件是当cur为空时。

3、循环结束后也一定要让head和tail置NULL。

 3.3入队

  1. //入队
  2. void QueuePush(Queue* pq, QDataType x)
  3. {
  4. assert(pq);
  5. QNode* newnode =(QNode*)malloc(sizeof(QNode));
  6. assert(newnode);
  7. newnode->data = x;
  8. newnode->next = NULL;
  9. if (pq->tail == NULL)
  10. {
  11. assert(pq->head == NULL);
  12. pq->head = pq->tail = newnode;
  13. }
  14. else
  15. {
  16. pq->tail->next = newnode;
  17. pq->tail = newnode;
  18. }
  19. }

分析:

入队需要考虑两种情况,第一种情况是队为空,第二种情况为队不为空。

情况一:队为空

如果队为空,我们就需要让pq->head 和 pq->tail 都等于newnode。

情况二:队不为空

如果队不为空,我们需要让pq->tail的next指向newnode,再让pq->tail往后走,走到newnode的位置。

3.4出队

  1. //出队
  2. void QueuePop(Queue* pq)
  3. {
  4. assert(pq);
  5. assert(pq->head && pq->tail);
  6. if (pq->head == pq->tail)
  7. {
  8. free(pq->head);
  9. pq->head = pq->tail = NULL;
  10. }
  11. else
  12. {
  13. QNode* next = pq->head->next;
  14. free(pq->head);
  15. pq->head = next;
  16. }
  17. }

分析:

如果要出队的话,根据对的性质,就当于是头删

过程:

1、创建一个next用来保存head的下一个节点的地址,我们free(head),再让head等于我们的next。

2、如果出队到只剩一个节点,也就是pq->head->next == NULL(pq->head == pq->tail),我们free掉pq->head之后要将pq->head 和 pq->tail 置NULL。

 3.5判断是否为空

 直接判断头是否为空,如果头为空说明队列为空

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

3.6队列的大小

定义一个size变量,遍历一遍队列,每次走一步让size++即可。

  1. //队的大小
  2. size_t QueueSize(Queue* pq)
  3. {
  4. assert(pq);
  5. QNode* cur = pq->head;
  6. size_t size = 0;
  7. while (cur)
  8. {
  9. size++;
  10. cur = cur->next;
  11. }
  12. return size;
  13. }

3.7返回头结点的元素Data

  1. QDataType QueueFront(Queue* pq)
  2. {
  3. assert(pq);
  4. assert(pq->head);
  5. return pq->head->data;
  6. }

3.8返回尾结点的元素Data

  1. QDataType QueueBack(Queue* pq)
  2. {
  3. assert(pq);
  4. assert(pq->tail);
  5. return pq->tail->data;
  6. }

4.完整代码

2022_03_26 -- 队列/2022_03_26 -- 栈和队列 · 李兴宇/数据结构 - 码云 - 开源中国 (gitee.com)

5.测试

  1. void TestQueue()
  2. {
  3. Queue q;
  4. QueueInit(&q);
  5. QueuePush(&q, 1);
  6. QueuePush(&q, 2);
  7. printf("%d ", QueueFront(&q));
  8. QueuePop(&q);
  9. QueuePush(&q, 3);
  10. QueuePush(&q, 4);
  11. while (!QueueEmpty(&q))
  12. {
  13. printf("%d ", QueueFront(&q));
  14. QueuePop(&q);
  15. }
  16. printf("\n");
  17. }
  18. int main()
  19. {
  20. //TestStack();
  21. TestQueue();
  22. return 0;
  23. }

测试结果:

 (本篇完)

 

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

闽ICP备14008679号