版权声明:Andy https://blog.csdn.net/Alibaba_lhl/article/details/82984294
循环队列
循环队列是将顺序队列变为一个变成一个环状的空间。头尾指针以及队列元素之间的关系不变,只是在循环队列中,头尾指针“依环状增 1”的操作可用”模“运算来实现。通过取模运算,头指针和尾指针就可以在顺序表空间内以头尾衔接的方式循环移动。
队空条件:Q.front == Q.rear
队满条件:(Q.rear + 1)% MAXQSIZE == Q.rear(少用一个元素空间,即队列空间为m时,有m-1个元素就认为是队满)。
循环队列(顺序表实现)
#include <bits/stdc++.h>
#define MAXQSIZE 100 ///队列可能到达的最大长度
#define OK 1
#define ERROR 0
using namespace std;
typedef int QElemType;
typedef int Status;
typedef struct
{
QElemType *base; ///存储空间的基地址
int front; ///头指针
int rear; ///尾指针
}SqQueue;
Status InitQueue(SqQueue &Q) ///循环队列的初始化
{
Q.base = new QElemType[MAXQSIZE]; ///为队列分配一个最大容量为MAXQSIZE的数组空间
if(!Q.base) exit(OVERFLOW); ///存储内存失败
Q.front = Q.rear = 0; ///头指针和尾指针置为0,队列为空
return OK;
}
int QueueLength(SqQueue Q) ///循环队列的长度
{///返回Q的元素个数,即队列的长度
return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}
Status EnQueue(SqQueue &Q, QElemType e) ///队列入队
{///插入元素e为Q的新的队尾元素
if( (Q.rear+1)%MAXQSIZE == Q.front) return ERROR; ///尾指针在循环意义上加一等于头指针,表明队满
Q.base[Q.rear] = e; ///新元素插入队尾
Q.rear = (Q.rear+1)%MAXQSIZE; ///队尾指针加1
return OK;
}
Status DeQueue(SqQueue &Q, QElemType &e) ///循环队列的出队
{///删除Q的队头元素,用e返回其值
if(Q.front == Q.rear) return ERROR; ///队空
e = Q.base[Q.front]; ///保存队头元素
Q.front = (Q.front+1)%MAXQSIZE; ///队头元素加1
return OK;
}
QElemType GetHead(SqQueue Q) ///取循环队列的队头元素
{///返回队列的队头元素,不修改头指针
if(Q.front != Q.rear) return Q.base[Q.front]; ///队列非空
}
void Travel(SqQueue Q) ///遍历队列
{
int x = Q.front;
while(x != Q.rear)
{
cout<< Q.base[x] << " ";
x++;
x %= MAXQSIZE;
}
cout<< endl << endl;
}
int main()
{
SqQueue Q;
QElemType e;
cout<< "1. 建立队列" << endl;
cout<< "2. 入队" << endl;
cout<< "3. 出队" << endl;
cout<< "4. 队头元素" << endl;
cout<< "5. 队列长度" << endl;
cout<< "6. 遍历队列" << endl;
int choose = -1;
while(choose)
{
cout<< "请选择:";
cin>> choose;
switch(choose)
{
case 1:
{
if(InitQueue(Q)) cout<< "队列建立成功!\n\n";
else cout<< "队列建立失败\n\n";
}
break;
case 2:
{
cout<< "请输入入队元素:";
cin>>e;
if(EnQueue(Q, e)) cout<< "入队成功!\n\n";
else cout<< "入队失败!\n\n";
}
break;
case 3:
{
if(DeQueue(Q, e)) cout<< "出队元素为: " << e << endl << endl;
else cout<< "出队失败!\n\n";
}
break;
case 4:
{
if(Q.front == Q.rear) cout<< "队列为空!\n\n";
else cout<< "队头元素为:" << GetHead(Q) << endl << endl;
}
break;
case 5:
{
cout<< "队列长度为:" << QueueLength(Q) << endl << endl;
}
break;
case 6:
{
Travel(Q);
}
}
}
return 0;
}
循环队列(链表实现)
用带有头结点的单链表存储结构实现队列。
#include <bits/stdc++.h>
#define OK 1
#define ERROR -1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef int Status;
typedef int QElemType;
typedef struct QNode ///队列的存储结构
{
QElemType data;
struct QNode *next;
}QNode, *QueuePtr;
typedef struct
{
QueuePtr front; /// 队头指针
QueuePtr rear; /// 队尾指针
}LinkQueue;
QueuePtr p;
int length = 0;
Status InitQueue(LinkQueue &Q) ///构造一个空队列
{
Q.front = Q.rear = new QNode; ///生成新结点作为头结点,队头和队尾指针都指向此节点
Q.front -> next = NULL; ///头结点指针置为空域
length = 0;
return OK;
}
Status EnQueue(LinkQueue &Q, QElemType e) ///插入元素e为Q的新的队尾元素
{///和顺序循环队列入队操作不同的是,链队在入队前不需要判断队是否满,而是需要为入队
///元素分配一个结点空间
p = new QNode; ///为入队元素分配结点空间,用指针p指向
p->data = e; ///将新结点数据域置为e
p->next = NULL; Q.rear->next = p; ///将新结点插入到队尾
Q.rear = p; ///修改队尾指针
length++;
return OK;
}
Status DeQueue(LinkQueue &Q, QElemType &e) ///删除Q的队头元素,用e返回其值
{
if(Q.front == Q.rear) return ERROR; /// 若队列为空,返回ERROR
p = Q.front->next; /// p指向队头元素
e = p->data; ///e保存队头元素的值
Q.front->next = p->next; ///修改头结点的指针域
if(Q.rear == p) Q.rear = Q.front; ///最后一个元素被删,队尾指针指向头结点
delete p; ///释放原头元素的空间
length--;
return OK;
}
QElemType GetHead(LinkQueue Q) ///返回Q的队头元素,不修改队头指针
{
if(Q.front != Q.rear) return Q.front->next->data; ///返回队头元素的值,队头指针不变
}
void Travel(LinkQueue Q)
{
if(Q.front == Q.rear) return ;
p = Q.front->next;
while(1)
{
cout<< p->data << " ";
if(p==Q.rear) break;
p = p->next;
}
cout<< endl << endl;
}
int main()
{
LinkQueue Q;
QElemType e;
cout<< "1. 建立队列" << endl;
cout<< "2. 入队" << endl;
cout<< "3. 出队" << endl;
cout<< "4. 队头元素" << endl;
cout<< "5. 队列长度" << endl;
cout<< "6. 遍历队列" << endl;
int choose = -1;
while(choose)
{
cout<< "请选择:";
cin>> choose;
switch(choose)
{
case 1:
{
if(InitQueue(Q)) cout<< "队列建立成功!\n\n";
else cout<< "队列建立失败\n\n";
}
break;
case 2:
{
cout<< "请输入入队元素:";
cin>>e;
if(EnQueue(Q, e)) cout<< "入队成功!\n\n";
else cout<< "入队失败!\n\n";
}
break;
case 3:
{
if(DeQueue(Q, e)) cout<< "出队元素为: " << e << endl << endl;
else cout<< "出队失败!\n\n";
}
break;
case 4:
{
if(Q.front == Q.rear) cout<< "队列为空!\n\n";
else cout<< "队头元素为:" << GetHead(Q) << endl << endl;
}
break;
case 5:
{
cout<< "队列长度为:" << length << endl << endl;
}
break;
case 6:
{
Travel(Q);
}
}
}
return 0;
}