1.队列是什么?
队列queue是只允许在一段进行插入操作、而在另一端进行删除操作的线性表。队列是一种先进先出的线性表,允许插入的一端称为队尾,允许删除的一段称为队头。
引入两个指针,front指针指向队头元素,rear指针指向队尾元素的下一个位置。
2.循环队列结构
循环队列的代码简单,但是简单的代价就是我们需要事先知道数组的长度。
代码如下:
(1).首先定义一个循环队列
#define MAXSIZE 20
typedef bool Status;
typedef int QElemType; //没用模板
typedef struct {
QElemType data[MAXSIZE];
int rear; //定义一个尾部下标
int front; //定义一个头部下标
}SqQueue;
(2).定义初始化函数和元素个数函数
void InitQueue(SqQueue *Q)
{
Q->front = 0;
Q->rear = 0;
}
int QueueLength(SqQueue Q)
{
return (Q.rear - Q.front + MAXSIZE) % MAXSIZE; //返回当前元素个数
}
(3).定义入栈函数和出栈函数
Status EnQueue(SqQueue *Q, QElemType e)
{
if ((Q->rear + 1) % MAXSIZE == Q->front) //判断队列是否已满
return false;
Q->data[Q->rear] = e;
Q->rear = (Q->rear + 1) % MAXSIZE; //将队尾指针后移一位,若到最后则将其安排到队列头部
return true;
}
Status DeQueue(SqQueue *Q, QElemType *e)
{
if (Q->front == Q->rear) //判断队列是否为空
return false;
*e = Q->data[Q->front];
Q->front = (Q->front + 1) % MAXSIZE; //将队头指针后移一位,若到达最后则转到队列头部
cout << "输出出队列的元素:";
cout << Q->data[0] << endl; //此时的元素为10
delete e; //删除指向地址的内容
return true;
}
(4).整体代码如下:
#include <iostream>
#define MAXSIZE 20
typedef bool Status;
typedef int QElemType;
using namespace std;
typedef struct {
QElemType data[MAXSIZE];
int rear;
int front;
}SqQueue;
void InitQueue(SqQueue *Q); //初始化一个空队列
int QueueLength(SqQueue Q); //返回Q的元素个数
Status EnQueue(SqQueue *Q, QElemType e); //声明入队列操作
Status DeQueue(SqQueue *Q, QElemType *e); //声明出队列操作
int main()
{
SqQueue *q = new SqQueue; //new分配一个动态内存存储SqQueue
QElemType *e1 = new QElemType; //new分配一个动态内存存储QElemType
InitQueue(q);
cout << "空队列长度:";
cout << QueueLength(*q)<<endl;
bool en = EnQueue(q, 10); //入队列
cout << "输出入队列后的front下标";
cout << q->front<<endl;
cout << "输出入队列后的rear下标";
cout << q->rear << endl;
cout << "输出入队列的元素10:";
cout << q->data[0] << endl;
en = DeQueue(q, e1); //出队列
cout<< "输出出队列后的front下标";
cout << q->front << endl;
cout << "输出出队列后的rear下标";
cout << q->rear << endl; //front=rear说明此时为空栈
}
void InitQueue(SqQueue *Q)
{
Q->front = 0;
Q->rear = 0;
}
int QueueLength(SqQueue Q)
{
return (Q.rear - Q.front + MAXSIZE) % MAXSIZE;
}
Status EnQueue(SqQueue *Q, QElemType e)
{
if ((Q->rear + 1) % MAXSIZE == Q->front) //判断队列是否已满
return false;
Q->data[Q->rear] = e;
Q->rear = (Q->rear + 1) % MAXSIZE; //将队尾指针后移一位,若到最后则将其安排到队列头部
return true;
}
Status DeQueue(SqQueue *Q, QElemType *e)
{
if (Q->front == Q->rear) //判断队列是否为空
return false;
*e = Q->data[Q->front];
Q->front = (Q->front + 1) % MAXSIZE; //将队头指针后移一位,若到达最后则转到队列头部
cout << "输出出队列的元素:";
cout << Q->data[0] << endl; //此时的元素为10
delete e; //删除指向地址的内容
return true;
}
输出结果如下:
空队列长度:0
输出入队列后的front下标0
输出入队列后的rear下标1
输出入队列的元素10:10
输出出队列的元素:10
输出出队列后的front下标1
输出出队列后的rear下标1
3.队列的链式存储结构
1。链式队列
队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已,我们把它简称为链队列
2.链队列定义
typedef int QElemType;
typedef struct QNode //结点结构
{
QElemType data;
struct QNode *next;
}*QueuePtr;
typedef struct //队列的链表结构
{
QueuePtr rear, front;//队头、队尾指针
}LinkQueue;
3.链队列入队函数
/*插入元素e为Q的新的队尾元素*/
Status EnQueue(LinkeQueue *Q, QElemType e)
{
QueuePtr s = new QNode;
if (!s) //如果分配内存失败
return false;
/*初始化新增结点*/
s->data = e;
s->next = nullptr;
/*新结点入队*/
Q->rear->next = s;
Q->rear = s;
delete s''
return true;
}
4.链队列出队函数
/*若队列不空,删除Q的队头元素*/
Status DeQueue(LinkQueue *Q, QElemType *e)
{
QueuePtr p;
if (Q->rear == Q->front)
return false;
p = Q->front->next; //队头为头结点的下一个结点
*e = p->data;
Q->front->next = p->next;
if (Q->rear == p)
Q->rear = Q->front; //若队尾结点等于队头结点,说明此时队列为空,则队尾应该等于头结点
delete p;
return true;
}