定义:队列也是一种受限的线性表。它限定所有的插入只能在表的一端进行,所有的删除只能在表的另一端进行。先进先出(FIFO)原则。队头front,队尾rear。队列的存储方式主要有顺序存储和链式存储。
队列的顺序存储结构
和顺序表一样,使用一个一维数组存放当前队列中的元素。由于队列、队头、队尾位置总是变化的,因此使用两个 Int 型变量 front 和 rear 分别指示当前队头元素和队尾元素在数组中的位置。但是要注意:front存放的是当前队头元素的位置,rear存放的是当前队尾元素的下一个位置,即下一个将要入队元素的位置。

但是由上图可以看出,随着入队和出队进行,队列元素逐渐向数组末端移动,当rear移出数组时,尽管前端有空余,不能入队,产生假溢出。解决方法:采用循环队列。如下图,当元素出队,front顺时针加1,当元素出队,rear顺时针加1.

通过取余操作实现front和rear的循环移动:
rear进一:rear=(rear+1)%maxsize
front进一:front=(front+1)%maxsize
循环队列使用一个int变量count记录队列中元素个数,判断队空或者满。队空和队满时都有rear=front。
//字符型循环队列类的定义
#include <iostream>
class Queue
{
public:
Queue(int m=10);
~Queue(){ delete[] elem; };
bool IsEmpty(){ return count == 0; }
bool IsFull(){ return count == maxsize; }
bool EnQueue(const char &x);
bool DeQueue();
bool Front(char &x); //将队头元素取到x
int Length(){ return count; }
void ClearQueue();
private:
int front, rear;
int count;
int maxsize;
char* elem;
};
Queue::Queue(int m)
{
elem = new char[m];
maxsize = m;
front = 0;
rear = 0;
count = 0;
}
bool Queue::EnQueue(const char &x)
{
if (IsFull()) return false;
elem[rear] = x;
rear = (rear + 1) % maxsize;
count++;
return true;
}
bool Queue::DeQueue()
{
if (IsEmpty()) return false;
front=(front+1)%maxsize;
count--;
return true;
}
bool Queue::Front(char &x)
{
if (IsEmpty())return false;
x = elem[front];
//front = (front + 1) % maxsize;
//count--;
return true;
}
void Queue::ClearQueue()
{
front = rear = 0;
count = 0;
}
队列的链式存储结构
用只允许子啊表头删除和表尾插入的单链表实现。设置两个指针,指向头节点的front和指向尾节点的rear。

依旧使用count记录队列中元素个数。
//链式存储结构的队列类定义
class LinkedQueue;
class Node
{
friend class LinkedQueue;
private:
char data;
Node* next;
};
class LinkedQueue
{
public:
LinkedQueue();
~LinkedQueue();
bool IsEmpty(){ return count == 0; }
void EnQueue(const char &x); //入队,由于肯定不会出现full情况,所以不用返回true/false
bool DeQueue(); //出队
bool Front(char &x); //取队头元素到x,但是不出队
void ClearLinkedQueue();
private:
int count;
Node *front, *rear;
};
LinkedQueue::LinkedQueue()
{
front = rear = 0;
count = 0;
}
LinkedQueue::~LinkedQueue()
{
ClearLinkedQueue();
}
void LinkedQueue::EnQueue(const char &x)
{
Node *p = new Node;
p->data = x;
p->next = 0;
if(!IsEmpty())rear->next = p;
else front = rear = p; //当队列本来为空时,插入一个结点后,front和rear同时指向新结点
rear = p;
count++;
}
bool LinkedQueue::DeQueue()
{
if (IsEmpty())return false;
Node* p; //出队列时,申请一个新结点指针暂存front,将front后移后,删除原来front指向的内存
p = front;
front = front->next;
delete p;
count--;
return true;
}
bool LinkedQueue::Front(char &x)
{
if (IsEmpty())return false;
x = front->data;
return true;
}
void LinkedQueue::ClearLinkedQueue()
{
Node *p;
p = front;
while (front != 0)
{
p = front->next;
delete front;
front = p;
}
front = rear = 0;
count = 0;
}