队列的定义:
一种可以实现“先进先出”的存储结构,类似于排队去买票,先排的先进去;可以在两端进行操作,但是只能固定在一端插入固定在一端删除;而栈只能在一端进行插入和删除的操作
队列的分类:
链式队列【用链表实现】—— 很简单了,跟之前没啥区别,我们就不讲了
静态队列【用数组实现】—— 静态队列通常都必须是循环队列,算是有点难度了
循环队列讲解:
(1)静态队列为什么必须是循环队列
如果是传统的数组的话,出队要从 Front 出,那它只能加,入队要从 Rear 入,它也只能加,那你下面的空间都浪费了,所以这里循环队列中,循环的意思是:如果那个 Rear 加到头了,那么就让 Rear 可以循环到数组最开始的位置,Front 也是一样的道理
举例:
① 最开始,从 front 到 rear,里面只有一个数据 c
② 此时我们想把 “中” 这个元素放进去,那就把 rear 移下去设置为一个循环队列,此时数据有两个,分别为 c 和 中
③ 此时我们又想删除一个元素,那 front 就只能加,c 元素就只能被删掉,队列里还有一个元素就是 中
(2)循环队列需要几个参数来确定
需要 Front 参数 和 Rear 参数
(3)循环队列这两个参数的含义
① 队列初始化时:Front 和 Rear 都是零
② 队列非空时: Front 指队列的最前面的那个元素, Rear指队列最后面那个元素后面一个位置
③ 队列空时:Front 和 Rear 相等,但是不一定是零
(4)循环队列入队伪算法讲解
入队是从尾部入队的,总共需要两步完成
① 先把入队的元素放在 rear 的位置
② 然后 rear = (rear + 1) % 数组长度 【因为循环队列有特殊情况】,不要直接就 rear = rear + 1
(5)循环队列出队伪算法讲解
出队是从头部出队的,只要一步就完成,或者说你想保存出队那个元素的话就加一个步骤
front = (front + 1) % 数组长度
(6)如何判断循环队列是否为空
如果 front 和 rear 相等,则说明这个循环队列就是空的
(7)如何判断循环队列是否已满
画草图模拟的时候用画圈圈的方式来进行,这样更加方便理解
首先要明确的一点是在循环队列中 front 和 rear 的大小没有绝对的关系
想要满的情况,那么需要满足:rear = front【这与循环队列判定空一致啊!怎么办?】
① 可以多定义一个队列元素个数的参数,通过这个参数来判断就可以了
② 队列可以放6个值,但规定只放5个,这个问题就解决了【常用】—— front = (rear + 1) % 数组长度
一些名称问题需要注意:
对于栈,我们常用的是 Top 和 Bottom,指针是从 Top 指向 Bottom,压栈出栈都是在 Top 进行
对于队列,我们常用的是 Front 和 Rear,指针是从 Front 指向 Rear,入队在 Rear 进行,出队在 Front 进行【本质还是链表】,F 指向第一个元素,R 指向最后一个元素的下一个元素