原理解析
看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;
}