一:题目
二:思路讲解
前提:
a:本文采取数组来实现队列去解决题目
b:开辟k+1个空间,front指向队首,rear指向队尾的后一个,rear这样会更好的判空和判满
以下根据pop和push感受满和空以及所有的边界的处理
1:初始状态
解释:当front == rear 即空
2 :push 1 2 3 4
解释:此时就是满了,那再push一个5会怎样?
3:在满的情况push 5
解释:得到判满条件(rear+1)%(k+1)== front,当rear的下一个就是front的时候就代表满了
Q:为什么不直接rear+1 = front?
A:这只适用于rear在数组非末尾位置的时候,而上面的表达式均适用
4:pop 1 2
5:push5 6
解释:rear的边界处理:rear = (rear+1)%(k+1)
6:在满的情况下 push 7
解释:这是rear在非末尾的位置的判满, (rear+1)%(k+1)== front同样适用
7:pop 3 4 5 6 得到空
解释:
1:可得只要rear和front相等,就是空
2:front的边界处理 :front =(front)%(k+1)
总结:
通过这几步我们可知,满和空的判断表达式 ,以及front和rear超过边界的处理表达式
满:(rear+1)%(k+1)== front(rear 的下一个是front就是满)
空:front == rear
rear超过边界:rear = (rear)%(k+1)
front超过边界:front =(front)%(k+1)
边界处理就是(下标)取模(数组空间)
最后一个边界处理:取队尾数据
当rear下标为0 的时候,这时候取队尾,rear-1 会等于-1,所以需要处理
1:三目操作符 rear = rear==0?k:rear
2:取模:rear = (rear+k)%(k+1)
这两种方法都适用与所有的取队尾
三:代码展示及其解释
1:初始化
解释:定义我们需要的值
2: MyCircularQueue(k)
: 构造器,设置队列长度为 k 。
解释:malloc k+1个整形的数组空间给a
3:isEmpty()
: 检查循环队列是否为空
解释:根据我们前文的判空表达式
4:isFull()
: 检查循环队列是否已满
解释:根据我们前文的判满表达式
5:enQueue(value)
: 向循环队列插入一个元素。如果成功插入则返回真。
解释:
先判满,满了,则无法插入,返回false
有空间,根据前文插入到下标为rear处,再rear要++
最后再通过rear的边界的处理的表达式处理rear
6:deQueue()
: 从循环队列中删除一个元素。如果成功删除则返回真。
解释:
先判空,空了,则无法删除,返回false
能删,直接front++
最后再通过front的边界的处理的表达式处理front
7:Front
: 从队首获取元素。如果队列为空,返回 -1 。
解释:直接返回front处的数据
8:Rear
: 获取队尾元素。如果队列为空,返回 -1 。
解释:通过的前文的取队尾的rear的处理表达式来取队尾
1:三目操作符 rear = rear==0?k:rear
2:取模:rear = (rear+k)%(k+1)
我用的第二种方法
9: 销毁队列
解释:先free a ,再free obj