原理解析
看main部分的注释,对照着函数,应该能看懂。
#include <iostream>
class Queue {public:static constexpr int MAX_SIZE = 5;int items[MAX_SIZE];int front, rear;Queue() : front(-1), rear(-1) {}void enqueue(int value) {if ((rear + 1) % MAX_SIZE == front) {std::cout << "Queue is full" << std::endl;return;}if (front == -1) {front = rear = 0;} else {rear = (rear + 1) % MAX_SIZE;}items[rear] = value;}int dequeue() {if (front == -1) {std::cout << "Queue is empty" << std::endl;return -1;}int removedItem = items[front];if (front == rear) {front = rear = -1;} else {front = (front + 1) % MAX_SIZE;}return removedItem;}void display() {if (front == -1) {std::cout << "Queue is empty" << std::endl;return;}int i = front;while (true) {std::cout << items[i] << " ";if (i == rear) break;i = (i + 1) % MAX_SIZE;}std::cout << std::endl;}
};
int main() {Queue q;// 插入第1个值,放在索引为0的位置q.enqueue(11);std::cout << "front:" << q.front << " rear:" << q.rear << std::endl;// 每插入1个值,rear前进1位q.enqueue(21);std::cout << "front:" << q.front << " rear:" << q.rear << std::endl;q.enqueue(31);q.enqueue(41);q.enqueue(51);std::cout << "front:" << q.front << " rear:" << q.rear << std::endl;// 插入5个值后,rear为4,数组已满// 每次插入前会先检查rear的下一位是否有空位,现在rear的下一位回到了索引0,而索引0现在被front占用,所以没有空位。q.enqueue(61); // 插入失败// 每删除1个值,front前进1位q.dequeue();std::cout << "front:" << q.front << " rear:" << q.rear << std::endl;q.dequeue();q.dequeue();q.dequeue();std::cout << "front:" << q.front << " rear:" << q.rear << std::endl;// 删除4个值后,front为4// 每次删除前会先检查front是否等于rear,如果等于说明只剩最后1个值了,再次删除就是清空数组q.dequeue();// 已经是空数组 不能再删除q.dequeue(); // 删除失败std::cout << std::endl;// 插入3个后rear为2q.enqueue(12);q.enqueue(22);q.enqueue(32);std::cout << "front:" << q.front << " rear:" << q.rear << std::endl;// 删掉1个后front为1q.dequeue();std::cout << "front:" << q.front << " rear:" << q.rear << std::endl;q.enqueue(42);q.enqueue(52);std::cout << "front:" << q.front << " rear:" << q.rear << std::endl;// 此时rear为4,rear的下一位回到索引0,此时front为1,并没有占用索引0,所以后面还能插入q.enqueue(62);std::cout << "front:" << q.front << " rear:" << q.rear << std::endl;// 现在rear为0,下一位是1,但1被front占用,数组满了,不能再插入q.enqueue(72); // 插入失败std::cout << std::endl;// 打印数组 从front开始到rear 每次循环索引步进1q.dequeue();q.dequeue();q.enqueue(13);std::cout << "front:" << q.front << " rear:" << q.rear << std::endl;// 现在front=3,rear=1,当索引步进到1时,说明打印完了,退出循环。q.display();return 0;
}
包装都头文件
实际使用要修改的地方,数组的大小,数组的类型。
还有插入函数的参数类型,删除函数的返回类型,都要改成数组中的元素类型。
// Queue.h
#ifndef QUEUE_H
#define QUEUE_H
#include <iostream>
class Queue {private:static constexpr int MAX_SIZE = 5;int items[MAX_SIZE];int front, rear;public:Queue() : front(-1), rear(-1) {}void enqueue(int value) {if ((rear + 1) % MAX_SIZE == front) {std::cout << "Queue is full" << std::endl;return;}if (front == -1) {front = rear = 0;} else {rear = (rear + 1) % MAX_SIZE;}items[rear] = value;}int dequeue() {if (front == -1) {std::cout << "Queue is empty" << std::endl;return -1;}int removedItem = items[front];if (front == rear) {front = rear = -1;} else {front = (front + 1) % MAX_SIZE;}return removedItem;}void display() {if (front == -1) {std::cout << "Queue is empty" << std::endl;return;}int i = front;while (true) {std::cout << items[i] << " ";if (i == rear)break;i = (i + 1) % MAX_SIZE;}std::cout << std::endl;}
};
#endif
调用
// main.cpp
#include "Queue.h"
int main() {Queue q;q.enqueue(10);q.enqueue(20);q.enqueue(30);q.display();std::cout << "Dequeued: " << q.dequeue() << std::endl; // 获取删除的值 也就是先进先出std::cout << "Dequeued: " << q.dequeue() << std::endl;q.display();q.enqueue(40);q.display();std::cout << "Dequeued: " << q.dequeue() << std::endl;std::cout << "Dequeued: " << q.dequeue() << std::endl;std::cout << "Dequeued: " << q.dequeue() << std::endl; // 删除失败return 0;
}
优化
最好改成类模版,实际使用中不需要打印函数,插入函数的参数可以改成引用。删除元素的返回值因为是局部变量,无法用移动语义优化。
如果对性能要求不高,可以把数组改成std::vector,这样在构造对象时就可以指定数组大小。这里更注重性能,所以手动修改数组大小。
// Queue.h
#ifndef QUEUE_H
#define QUEUE_H
#include <iostream>
#include <utility>
template <typename T> class Queue {private:static constexpr int MAX_SIZE = 1000;T items[MAX_SIZE];int front, rear;public:Queue() : front(-1), rear(-1) {}void enqueue(const T &value) {if ((rear + 1) % MAX_SIZE == front) {std::cout << "Queue is full" << std::endl;return;}if (front == -1) {front = rear = 0;} else {rear = (rear + 1) % MAX_SIZE;}items[rear] = value;}T dequeue() {if (front == -1) {std::cout << "Queue is empty" << std::endl;return T{};}T removedItem = items[front];if (front == rear) {front = rear = -1;} else {front = (front + 1) % MAX_SIZE;}return removedItem;}
};
#endif
测试
#include "Queue.h"
#include <chrono>
#include <iostream>struct bar {float open;float height;float low;float close;
};int main() {Queue<bar> q;bar b1 = {10.0f, 15.0f, 8.0f, 12.0f};bar b2 = {20.0f, 16.0f, 9.0f, 13.0f};q.enqueue(b1);q.enqueue(b2);q.enqueue({30, 17, 10, 14}); // 直接使用初始化列表传入参数q.enqueue({40.2, 18.2, 19.2, 15.2});std::cout << q.dequeue().close << std::endl;std::cout << q.dequeue().close << std::endl;std::cout << q.dequeue().close << std::endl;std::cout << q.dequeue().close << std::endl; // 数组清空std::cout << q.dequeue().close << std::endl; // 删除失败return 0;
}