赞
踩
队列是FIFO型结构,即先进先出,即入队(队尾添加)和出队(队首删除)。一个队列,则分首尾。如何分?两个方法:动态数组和指向队列头部的索引。入队会向队列追加一个新元素,而出队会删除第一个元素。 所以我们需要一个索引来指出起点。
- #include<iostream>
- #include<vector>
- using namespace std;
-
- class MyQueue{
- private:
- vector<int> data; //存储元素
- int p_start; //起始位置的指针
- public:
- MyQueue(){p_start = 0;}
- //往队列插入一个元素,成功返回true
- bool inQueue(int x){
- data.push_back(x);
- return true;
- }
- //从队列删除一个元素,成功返回true
- bool delQueue(){
- if(isEmpty()){
- return false;
- }
- p_start++;
- return true;
- }
- //获取队列前面的元素
- int Front(){return data[p_start];}
- //检查队列是否为空
- bool isEmpty(){
- return p_start >= data.size();
- }
- };
- int main()
- {
- MyQueue q;
- q.inQueue(5);
- q.inQueue(1);
- q.inQueue(8);
- if(!q.isEmpty()){
- cout<<q.Front()<<endl;
- }
- q.delQueue();
- if(!q.isEmpty()){
- cout<<q.Front()<<endl;
- }
- q.delQueue();
- if(!q.isEmpty()){
- cout<<q.Front()<<endl;
- }
- }
上面的实现适用于添加比较少的元素,随着起始指针p_start的移动,会浪费越来越多的空间。
更有效的方法是使用循环队列。 具体来说,我们可以使用固定大小的数组
和两个指针
来指示起始位置和结束位置。 目的是重用
我们之前提到的被浪费的存储
。
在循环队列中,我们使用一个数组
和两个指针(head
和 tail
)。 head
表示队列的起始位置,tail
表示队列的结束位置。
- class MyCircularQueue {
- private:
- vector<int> data;
- int head;
- int tail;
- int size;
- public:
- //在此处初始化数据结构。将队列的大小设置为 k。
- MyCircularQueue(int k) {
- data.resize(k);
- head = -1;
- tail = -1;
- size = k;
- }
-
- //将元素插入循环队列。如果操作成功,则返回 true。
- bool enQueue(int value) {
- if (isFull()) {
- return false;
- }
- if (isEmpty()) {
- head = 0;
- }
- tail = (tail + 1) % size;
- data[tail] = value;
- return true;
- }
-
- //从循环队列中删除元素。如果操作成功,则返回 true。
- bool deQueue() {
- if (isEmpty()) {
- return false;
- }
- if (head == tail) {
- head = -1;
- tail = -1;
- return true;
- }
- head = (head + 1) % size;
- return true;
- }
-
- //从队列中获取首元素。
- int Front() {
- if (isEmpty()) {
- return -1;
- }
- return data[head];
- }
-
- //获取队列最后一个元素
- int Rear() {
- if (isEmpty()) {
- return -1;
- }
- return data[tail];
- }
-
- //检查循环队列是否为空。
- bool isEmpty() {
- return head == -1;
- }
-
- //检查循环队列是否已满。
- bool isFull() {
- return ((tail + 1) % size) == head;
- }
- };
大多数流行语言都提供内置的队列库,因此无需重新发明轮子。
如前所述,队列有两个重要的操作,入队 enqueue 和出队 dequeue。 此外,我们应该能够获得队列中的第一个元素,因为应该首先处理它。
下面是使用内置队列库及其常见操作的一些示例:
- #include <iostream>
- #include<queue>
-
- using namespace std;
- 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;
- }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。