队列
特点:
线性存储结构,FIFO(First In First Out),队尾加元素,队头删元素。
操作:
入队、出队、队列个数、是否为空、队首元素
分类:
基于标准库、数组、链表
编程实现:(c++)
1.标准库
#include<queue> //头文件
queue<int> q; //定义
q.empty(); //空
q.size(); //个数
q.pop();//删除队首,不返回
q.front();//返回队首,不删除
q.push();//队尾压新元素
q.back();//返回队尾,不删除
2.数组
通常使用 循环队列,防止出队时O(n)操作。
需要设定一个最大队列长度,若用户无法估计队列最大长度,宜采用链表。
begin指向队头第一个,end指向队尾下一个。
如何判断队列空还是满?
一般情况下,空和满都是
begin==end
为区别空满:少用一个元素位。
若空:
begin==end
若满:
begin == (end+1)%capacity
#include <iostream>
#include <queue>
using namespace std;
template <typename T>
class arrayqueue {
public:
arrayqueue(int c = 0): capacity(c), begin(0), end(0), que(nullptr) {
que = new T[capacity];
}
~arrayqueue() {
delete[]que;
}
bool isEmpty() {
return (begin == end);
}
int size() {
return (capacity - begin + end) % capacity;
//return que[0];
}
bool push(T t) {
if ((end + 1) % capacity == begin)
return false;
que[end] = t;
end = (end + 1) % capacity;
return true;
}
bool pop() {
if (end == begin)
return false;
begin = (begin + 1) % capacity;
return true;
}
T front() {
if (end == begin)
return false;
return que[begin];
}
public:
int capacity;
int begin; //指当前头
int end; //指向下一个赋值处
T *que;
};
int main() {
arrayqueue<int> Aqueue(6); //实际maxsize = 5
cout << "popempty" << Aqueue.pop() << endl;
cout << "isempty" << Aqueue.isEmpty() << endl;
for (int i = 0; i < 5; i++)
Aqueue.push(i);
cout << "front" << Aqueue.front() << endl;
cout << "pop" << Aqueue.pop() << endl;
cout << "front" << Aqueue.front() << endl;
cout << "push 6" << Aqueue.push(6) << endl;
cout << "end" << Aqueue.end << "begin" << Aqueue.begin << endl;
cout << "push 7 " << Aqueue.push(7) << endl;
cout << "size" << Aqueue.size() << endl;
cout << "isempty" << Aqueue.isEmpty() << endl;
return 0 ;
}
3.链表
#include <iostream>
#include <queue>
using namespace std;
template <typename T>
struct qnode {
public:
qnode *next;
T data;
qnode(qnode *n, T t): next(n), data(t) {
}
qnode(T t): data(t), next() {
}
qnode(): next(), data( ) {
}
};
template <typename T>
class queuenode {
public:
qnode<T> *head;
qnode<T> *feet;
int nodeNum;
public:
queuenode() {
qnode<T> *q = new qnode<T>();
head = q;
feet = q;
nodeNum = 0;
}
~queuenode() { //链表析构
}
bool isEmpty() {
return (nodeNum == 0);
}
void push(T t) {
feet->data = t;
feet -> next = new qnode<T>();
feet = feet->next;
nodeNum++;
}
bool pop() {
if (head == feet)
return false;
head = head->next;
nodeNum--;
return true;
}
int size() {
return nodeNum;
}
T front() {
if (nodeNum == 0)
return NULL;
return head->data;
}
};
int main() {
queuenode<int> qqnode;
cout << "empty" << qqnode.isEmpty() << endl;
cout << "front" << qqnode.front() << endl;
for (int i = 0; i < 5; i++) {
qqnode.push(i);
cout << qqnode.feet->data;
}
cout << endl;
cout << "size" << qqnode.size() << endl;
cout << "front" << qqnode.front() << endl;
cout << "pop" << qqnode.pop() << endl;
cout << "size" << qqnode.size() << endl;
cout << "front" << qqnode.front() << endl;
cout << "empty" << qqnode.isEmpty() << endl;
return 0 ;
}
应用
参考:
C++数据结构——队列
《画解数据结构》九张动图,画解队列
双端队列
特点:
线性存储结构,双端增删。
操作:
队头入队、队头出队、队尾入队、队尾出队、队列个数、是否为空、队首元素、队尾元素
分类:
基于标准库、数组、链表
编程实现:(c++)
1.标准库
详细参考:deque使用详解
#include<deque> //头文件
deque<int> q; //定义
q.empty(); //空
q.size(); //个数
q.front();//返回队首,不删除
q.push_front();//队头压新元素
q.push_back();//队尾压新元素
deque<int>::iterator::it = deq.begin();
deq.insert(it, (3,) 9); //在开始处插(3个)9
q.pop_front();//删除队首,不返回
q.pop_back();//
q.erase(iterator it);//删任意位置
q.clear();清空
q.front();
q.back();//返回队尾,不删除
q.at(n);//下标访问,越界返回异常