参考LeetCode的教程。
思想
两个线性数据结构,队列:FIFO,栈:LIFO。
基本实现
#include <iostream>
class MyQueue {
private:
// store elements
vector<int> data;
// a pointer to indicate the start position
int p_start;
public:
MyQueue() {p_start = 0;}
/** Insert an element into the queue. Return true if the operation is successful. */
bool enQueue(int x) {
data.push_back(x);
return true;
}
/** Delete an element from the queue. Return true if the operation is successful. */
bool deQueue() {
if (isEmpty()) {
return false;
}
p_start++;
return true;
};
/** Get the front item from the queue. */
int Front() {
return data[p_start];
};
/** Checks whether the queue is empty or not. */
bool isEmpty() {
return p_start >= data.size();
}
};
int main() {
MyQueue q;
q.enQueue(5);
q.enQueue(3);
if (!q.isEmpty()) {
cout << q.Front() << endl;
}
q.deQueue();
if (!q.isEmpty()) {
cout << q.Front() << endl;
}
q.deQueue();
if (!q.isEmpty()) {
cout << q.Front() << endl;
}
}
但是这种方法有个问题,就是耗内存,随着队列入队出队的操作,p_start的值越来越大,data的size也会越来越大,但是已经出队的数据还存在data里,造成浪费。
循环队列
class MyCircularQueue {
private:
vector<int> data;
int head;
int tail;
int size;
public:
/** Initialize your data structure here. Set the size of the queue to be k. */
MyCircularQueue(int k) {
data.resize(k);
head = -1;
tail = -1;
size = k;
}
/** Insert an element into the circular queue. Return true if the operation is successful. */
bool enQueue(int value) {
if (isFull()) {
return false;
}
if (isEmpty()) {
head = 0;
}
tail = (tail + 1) % size;
data[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) {
head = -1;
tail = -1;
return true;
}
head = (head + 1) % size;
return true;
}
/** Get the front item from the queue. */
int Front() {
if (isEmpty()) {
return -1;
}
return data[head];
}
/** Get the last item from the queue. */
int Rear() {
if (isEmpty()) {
return -1;
}
return data[tail];
}
/** Checks whether the circular queue is empty or not. */
bool isEmpty() {
return head == -1;
}
/** Checks whether the circular queue is full or not. */
bool isFull() {
return ((tail + 1) % size) == head;
}
};
使用
cpp提供了现成的库,基本用法:
#include <iostream>
int main() {
// 1. Initialize a queue.
queue<int> q;
// 2. Push new element.
q.push(5);
q.push(13);
q.push(8);
q.push(6);
// 3. Check if queue is empty.
if (q.empty()) {
cout << "Queue is empty!" << endl;
return 0;
}
// 4. Pop an element.
q.pop();
// 5. Get the first element.
cout << "The first element is: " << q.front() << endl;
// 6. Get the last element.
cout << "The last element is: " << q.back() << endl;
// 7. Get the size of the queue.
cout << "The size is: " << q.size() << endl;
}
主要用法
queue<type> q; // 定义队列q
q.empty(); // 是否为空
q.push(value); // 后加
q.pop(); // 前减
q.front(); // 返回队列头
q.back(); // 返回队列尾巴
q.size(); // 返回队列元素个数
补充一个递减队列的用法!!!
广度优先搜索(BFS)
部分参考广度优先搜索算法(附C++实现)
队列和 BFS
广度优先搜索(BFS)是一种遍历或搜索数据结构(如树或图)的算法。我们可以使用 BFS 在树中执行层序遍历。我们也可以使用 BFS 遍历图。例如使用 BFS 找到从起始结点到目标结点的路径,特别是最短路径。可以在更抽象的情景中使用 BFS 遍历所有可能的状态。在这种情况下,可以把状态看作是图中的结点,而以合法的过渡路径作为图中的边。