力扣的知识真是太多了,开帖记录一下才能加深自己的记忆,那么第一篇就献给队列吧!
队列
特点:先入先出
使用:
- 头文件:
#include<queue>
- 定义:
queue<int> q
也可以用动态数组vector<int> q
- 函数:
pop():队首元素出队
push(i):将元素i插入到队尾
size():返回队列中元素的个数
empty():判断队列是否为空
front():返回队列队首元素
back():返回队列队尾元素
//前4条在栈中同样适用,区别在返回元素时,栈是用top()返回栈顶元素
基础函数掌握好之后就开始进阶啦!
循环队列
实现原理:一个数组存放队列,两个指针(head和tail)。head表示队列的起始位置,tail表示队列的结束位置。
需要注意的是,因为head=tail可能代表队列为空,也可能代表队列为满,为了区分这两种情况,规定循环队列最多只能有MaxSize-1个队列元素,即当剩下的空间只有一个的时候,就视为队列已满。因此队列为空的判断为head==tail,队列为满的判断为head=(tail+1)%MaxSize。
代码:
执行用时:56 ms
class MyCircularQueue {
private:
vector<int> q;
int head;
int tail;
int size;
public:
/** Initialize your data structure here. Set the size of the queue to be k. */
MyCircularQueue(int k) {
q.resize(k); //resize(k):设置数组的大小为k
head = -1; //两个指针都初始化为-1(因为0就代表存在一个数据)
tail = -1;
size = k;
}
/** Insert an element into the circular queue. Return true if the operation is successful. */
bool enQueue(int value) {
if (isFull()) { //如果队列满了,返回false,添加数据失败
return false;
}
if (isEmpty()) { //因为空的时候head是-1,所以要记得给head也改变位置
head = 0;
}
tail = (tail+1) % size; //入队时尾指针后移一位(只要有加1的步骤,就随时可能数组越界,要加%回去)
q[tail] = value; //入队成功
return true;
}
/** Delete an element from the circular queue. Return true if the operation is successful. */
bool deQueue() {
if (isEmpty()) { //如果队列是空的,没有元素可以出队,宣布失败
return false;
}
if (head == tail) { //这里是提前判断了出队后队列是否为空,为了和数组定义时的首尾指针-1呼应,也算便于管理,只要队列空了,不管首尾指针停留在哪,都回归-1。
head = -1;
tail = -1;
return true;
}
head = (head+1) % size; //出队时首指针后移一位(只要有加1的步骤,就随时可能数组越界,要加%回去)
return true; //出队成功不需要操作,移动指针就行
}
/** Get the front item from the queue. */
int Front() {
if (isEmpty()) { //如果为空,返回-1
return -1;
}
return q[head]; //用来返回队列首元素
}
/** Get the last item from the queue. */
int Rear() {
if (isEmpty()) { //如果为空,返回-1
return -1;
}
return q[tail]; //用来返回队列尾元素
}
/** Checks whether the circular queue is empty or not. */
bool isEmpty() {
return head == -1; //因为在出队的时候就判断过如果首尾相等,队列为空,head回到-1,所以head==-1可以看作所有的为空条件。
}
/** Checks whether the circular queue is full or not. */
bool isFull() {
return head == (tail+1) % size; //队列满的判断(开头有说)
}
};
/**
* Your MyCircularQueue object will be instantiated and called as such:
* MyCircularQueue* obj = new MyCircularQueue(k);
* bool param_1 = obj->enQueue(value);
* bool param_2 = obj->deQueue();
* int param_3 = obj->Front();
* int param_4 = obj->Rear();
* bool param_5 = obj->isEmpty();
* bool param_6 = obj->isFull();
*/
应用到的课外函数:q.resize(k)
设置数组大小为k