队列的逻辑结构
队列:只允许在表的一端进行插入操作,在另一端进行删除操作;
(a1,a2,…,an-1,an);
队尾:允许插入的一端,相应地,位于队尾的元素成为队尾元素;
队头:允许删除的一端,相应地,位于队头的元素成为队头元素;
插入: 入队,进队;删除: 出队;
空队列 :不含任何数据元素的队列;
队列的操作特性:先进先出(First In First Out,FIFO);
InitQueue
输入:无 功能:初始化队列,创建一个空队列 输出:无
DestroyQueue
输入:无 功能:销毁队列,释放队列所占用的存储空间 输出:无 EnQueue
输入:元素值x 功能:在队尾插入一个元素 输出:如果插入成功,队尾增加了一个元素;否则返回失败信息
DeQueue 输入:无 功能:删除队头元素 输出:如果删除成功,返回被删元素值;否则给出失败信息
GetQueue
输入:无 功能:读取队头元素 输出:若队列不空,返回队头元素;否则给出失败信息
Empty 输入:无 功能:判断队列是否为空 输出:如果队列为空,返回1,否则,返回0
队列的顺序存储结构及其实现
顺序队列:队列的顺序存储;
如何表示队头:用数组的一端作为队头,从下标 0 处开始存放;
如何表示队尾:设变量rear存储队尾元素所在的下标;
队列的移动特点:整个队列向数组下标较大方向移动(单向性移动);
假溢出:数组空间上发生溢出,单数组的低端还有空闲空间;
为了解决假溢出问题,让数组下标循环起来;
循环队列:队列采用顺序存储,并且数组是头尾相接的循环结构;(既允许队列直接从数组中下标最大的延续到下标最小的位置;
程序技巧:求模(正余数)使得数组下标循环;
```cpp
if (rear + 1 > 4)
rear = 0;
else
rear++;
等价于rear = (rear + 1) % 5怎样判断队满和队空呢?为了区分队满和对空,可以浪费一个数组空间,front不放元素队满的条件是(rear+1)%QueueSize;对空的条件是rear == front
#include <iostream>
using namespace std;
const int Maxsize = 100;
int QueueSize = 100,front,rear;
int data[Maxsize];
构造函数
void init()
{
//构造函数
front = rear = -1;
//front = rear = Queuesize;
}
判空
int is_empty()
{//判空
if (rear == front)
return 1;
else
return 0;
}
入队
void enqueue(int x)
{
//入队操作
if ((rear + 1) % QueueSize == front)
throw "上溢";
rear = (rear + 1) % QueueSize;
data[rear] = x;
}
出队
int DeQueue()
{
//出队操作
if (rear == front)
throw "下溢";
front = (front + 1) % QueueSize;
return data[front];
}
取队头元素
int GetHead()
{//取队头元素
if (rear == front)
throw "下溢";
return data[(front + 1) % QueueSize];
}
int main(){
for(int i = 1; i <= 5; i ++) {
enqueue(i);
}
while(!is_empty()) {
cout << GetHead() << endl;
DeQueue();
}
}
#include <iostream>
#include <queue>
using namespace std;
queue<int> q;
int main() {
for(int i = 1; i <= 5; i ++) {
q.push(i);
}
while(q.size()) {
cout << q.front();
q.pop();
}
}
队列的链接存储结构及实现
链队列:队列的链式存储结构;我们建议采用带头结点的实现方式,因为,这样可以大大简化对队列的处理。链队列的入队
void LinkQueue<DataType> :: EnQueue(DataType x)
{
Node<DataType> *s = nullptr;
s = new Node<DataType>; //申请结点s
s->data = x; s->next = nullptr;
rear->next = s; rear = s;
}
取队头元素
DataType LinkQueue<DataType> :: DeQueue( )
{
DataType x;
Node<DataType> *p = nullptr;
if (rear == front) throw "下溢";
p = front->next; x = p->data;
front->next = p->next;
if (p->next == nullptr) rear = front;
delete p;
return x;
}
两栈共享空间
什么时候栈1为空?
top = -1;
什么时候栈2为空?
top = Stack_Size
top2 = top1 +1;
双端队列
双端队列是指允许两端都可以进行入队和出队操作的队列,其元素的 逻辑结构仍是线性结构。将队列的两端分别称为前端和后端,两端都可以入队和出队。
STL Deque 容器
deque采用模板类实现
deque deqT;
deque p;
在队尾添加元素:deque.push_pack(elem);
在对头插入一个数据:deque.push_front(elem);
删除最后一个数据:deque.pop_back();
删除容器第一个数据:deque.pop_front();
返回第一个数据: deque.front();
返回最后一个数据:deque.back();deque的大小
deque.size();返回容器中元素的个数;
deque.empty();判断容器是否为空;
deque.begin()
返回容器中第一个元素的迭代器。
deque.end()
返回容器中最后一个元素之后的迭代器。
deq.clear()
移除容器的所有数据