当前位置:   article > 正文

数据结构初阶 队列

数据结构初阶 队列

一. 队列的基本介绍

1. 基本概念

队列是基本数据结构的一种 它符合先进先出的原则

 我们来看图

 

大概就是这样子的一种情况 

我们想想看 应该用数组还是链表来实现这个结构方便一点呢

我想同学们心里现在肯定已经有了答案了

肯定不是数组

为什么呢?

因为我们如果用数组头作为队头的话 每次删数据就要往前移动很多组其他的数据

这里有同学肯定会有这样子的疑问?

不移动可不可行呢?

当然不可以 !

队列这种数据结构已经规定死了就是头出 尾进

所以说我们使用链表来实现这个数据结构

2. 代码表示

  1. typedef int QDateType;
  2. typedef struct QueueNode
  3. {
  4. struct QueueNode* next;
  5. QDateType date;
  6. }QNode;
  7. typedef struct Queue
  8. {
  9. QNode* head;
  10. QNode* tail;
  11. int size;
  12. }Queue;

仔细看

我们这里使用QueueNode来表示储存数据的一个个节点

使用Queue来表示两个指针 头和尾

可以看图理解快一点

二. 接口函数的实现 

1. 队列初始化

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

队列初始化实际上就是将队列的两个指针置空

我们来看看效果

这里没有传二级指针进去到底能不能将一级指针置空

成功将两个指针置空了

这是为什么呢?

因为我们的头和尾指针实际上是储存在一个结构体里面的

当我们将结构体的地址传进去的时候 结构体指针能够访问到结构体内部的内容(这两个指针)并且可以修改它们

2. 插入数据

这里插入数据我们要考虑两种情况

1.如果head和tail指针指向NULL,就需要将newnode赋给head和tail指针

2.head和tail不指向NULL,就将newnode的地址赋给tail->next,再将tail移到newnode即可

代码如下:

  1. //队进
  2. void QueuePush(Queue* pq, QDateType x)
  3. {
  4. assert(pq);
  5. //开辟新节点
  6. QNode* newnode = (QNode*)malloc(sizeof(QNode));
  7. if (newnode == NULL)
  8. {
  9. perror("malloc fail");
  10. return;
  11. }
  12. //赋值
  13. newnode->next = NULL;
  14. newnode->date = x;
  15. //判断是否为空
  16. if (pq->head == NULL)
  17. {
  18. pq->head = pq->tail = newnode;
  19. }
  20. else
  21. {
  22. pq->tail->next = newnode;
  23. pq->tail = newnode;
  24. }
  25. //个数要++
  26. pq->size++;
  27. }

 看看效果怎么样

可以运行

3. 删除数据

这里我们要注意的是

由于队列结构的特殊性

我们在打印数据的时候必须要删除数据

所以我们先写删除数据的接口函数

代码表示如下

  1. void QueuePop(Queue* pq)
  2. {
  3. assert(pq);
  4. assert(pq->head!=NULL);
  5. //只有一个节点
  6. if (pq->head->next == NULL)
  7. {
  8. free(pq->head);
  9. pq->head = pq->tail = NULL;
  10. }
  11. else
  12. {
  13. //保存下一位
  14. QNode* next = pq->head->next;
  15. free(pq->head);
  16. pq->head = next;//迭代
  17. }
  18. //个数要--
  19. pq->size--;
  20. }

看看效果:

可以运行

4. 摧毁队列

直接看代码:

  1. void QueueDestroy(Queue* pq)
  2. {
  3. assert(pq);
  4. //两个结构体依次销毁 先销毁QNode
  5. QNode* cur = pq->head;
  6. while (cur)
  7. {
  8. QNode* next = cur->next;
  9. free(cur);
  10. cur = next;
  11. }
  12. //再置空Queue
  13. pq->head = pq->tail = NULL;
  14. pq->size = 0;
  15. }

注意:两个结构体要依次销毁,类似(套娃) 

我们来看看效果

5. 判断为空

这个也很简单和栈差不多

这里就直接给代码了

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

6.返回大小

这个也很简单,因为我们在Queue结构体中已经定义过size了,我们直接返回就可以

直接看代码:

  1. //大小
  2. int QueueSize(Queue* pq)
  3. {
  4. assert(pq);
  5. return pq->size;
  6. }

7. 返回头数据

这个很简单 返回head的值就可以了

注意断言的使用

  1. //对头
  2. QDateType QueueFront(Queue* pq)
  3. {
  4. assert(pq);
  5. assert(!QueueEmpty(pq));
  6. return pq->head->date;
  7. }

8.返回尾数据

一样的简单

也要注意断言的使用

  1. //队尾
  2. QDateType QueueBack(Queue* pq)
  3. {
  4. assert(pq);
  5. assert(!QueueEmpty(pq));
  6. return pq->tail->date;
  7. }

以上便是本文所有内容了,如有错误请各位大佬不吝赐教,感谢留言

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

闽ICP备14008679号