《数据结构》C语言版 (清华严蔚敏考研版) 第三章 栈和队列 队列相关知识梳理与总结

发布于:2024-05-09 ⋅ 阅读:(36) ⋅ 点赞:(0)

个人主页李仙桎

   🔥 个人专栏: 《数据结构与算法》

⛺️生活的理想,就是为了理想的生活!

Alt

⛺️前言:各位铁汁们好啊!!!,今天继续学习数据结构相关的内容,后续不断更新数据结构有关知识内容!!希望各位铁汁多多支持!这一章节主要是《数据结构》第三章 栈和队列 队列的相关知识总结。

队列的介绍

队列(Queue)就像是食堂排队打饭的人群。想象一下你去食堂打饭,人们在打饭窗口形成一条线(队列)等待打饭。队列遵循一个很重要的原则:先进先出(First In, First Out,简称FIFO)。这意味着最先到达并排队的人将会是第一个打饭并离开队列的人,随后到达的人则依次排在队伍的后面,等待打饭。

队列是只允许在一端进行插入操作(入队),而在另一端进行删除操作(出队)的线性表

 

队列的存储结构

线性表有两种存储结构:顺序存储和链式存储,在栈中我们知道,栈存在两种存储结构,队列作为特殊的线性表,也同样存在这两种存储结构

 队列的顺序存储结构

队列的顺序存储结构,就是线性表的顺序表,只不过它只能尾进头出,我们在静态数组来存放元素,队头指针和队尾指针分别指向队头和队尾

初始化操作

入队操作

注意为什么队尾值需要取模运算,因为我们出队(删除表头元素)操作时候,我们静态数组的data[0]、data[1]...data[front]位置就会空,这可能会造成队头不在数组的起始位置。插入队列时候如果rear只是简单+1,那我们当继续向队列中添加元素而队尾已经达到数组的最末端时,若不采取任何措施,就无法再添加新的元素,即使数组的前部(队头之前的部分)是空闲的。这种情况看起来好像数组已经“溢出”了,但实际上是因为未充分利用数组的空间,称为“假溢出”。解决假溢出的办法就是后面满了,再从头开始,头尾相接的循环,把队列这种头尾相接的顺序结构称为循环队列,(rear+1)%MaxSize

难么怎么判断队列是空的还是满的?

我们让队列判空条件还是front=rear,

此时队列是满的,但是front等于rear,这个条件有有可能对应队列是空的,那么我们该怎样判断队列是满的还是空的?

解决办法:
①我们让队列判空条件还是front=rear,当队列满时,我们修改条件,使其保留一个元素空间,也就是队列满时,还有一个空闲单元。rear可能比front大,也可能比front小,相差一个位置即为满

 则队列满的条件是(rear+1)%MaxSize==front,队列的元素个数:(rear+MaxSize-front)%MaxSize

这种顺序存储若不是循环队列,算法性能不高,循环队列又面临着数组溢出的问题,我们接下来讲解队列的链式存储结构

②此外我们还可以再定义队列的时候加入一个int变量来记录当前队列的长度,插入成功size++。 删除成功size--。那么我们可以用size判断队列空还是满,此时不需要我们牺牲一个元素空间

#define MaxSize 10
typedef struct{
    ElemType data[MaxSize];
    int front,rear;
    int size;
} SqQueue;

 ③此外我们还可以再定义队列的时候加入一个int变量来记录最近进行的是插入还是删除

出队操作

队列的链式存储结构

链队列的构建

这里的队列是通过链表实现的,链式存储方式的好处在于它可以动态地分配内存,避免了顺序队列中可能发生的假溢出问题,同时也不需要在队列初始化时就确定其最大容量。

front指针指向队列的头部(第一个元素),而rear指针指向队列的尾部(最后一个元素)。这两个指针是实现队列基本操作(如入队和出队)的关键

此外可以在定义队列的时候加入一个int型的变量size存储队列中当前的元素数量。这个信息对于快速获取队列的大小,以及确定队列是否为空等操作非常有用。

初始化操作

入队操作

 

出队操作

双端队列


网站公告

今日签到

点亮在社区的每一天
去签到