一、引入
队列的顺序表示和实现
队列的顺序表示-用一维数组base[MAXQSIZE]
#define MAXQSIZE 100 //最大队列长
typedef struct{
Qelem *base; //初始化的动态分配存储空间
int front; //头指针,不是指针变量,若队列不空,只想队头元素
int rear; //尾指针,不是指针变量,若队列不空,指向队尾元素的下一个位置
}SqQueue;
初始:
front=rear=0;//队空
入队:
base[Q.rear]=e;//
rear++; //指向下一空间
出队:
e=base[Q.front];//出队
front++;
front=rear;//队空标志
当rear==MAXQSIZE时,发生溢出
- 若front=0,rear=MAXQSIZE时,再入队——真溢出;
- 若front!=0,rear=MAXQSZIE时,再入队——假溢出
如何解决假溢出问题?
- 将队中元素向对头移动,缺点是浪费时间,队中元素都要移动
- 将队空间设想成一个循环的表,即分配给队列的m个存储单元可以循环使用,当rear = =MAXQSIZE时,若向量的开始端空着,又可从头使用空着的空间。当front= =MAXQSIZE时,也是一样的。
即引入循环队列
base[0]接在base[MAXQSIZE-1]之后,若rear+1MAXQSIZE,则令rear=0;
实现方法:利用模(mod,即%)==求余运算。
插入元素:
Q.base[Q.rear]=e; //把值赋给尾指针所指空间
Q.rear=(Q.rear+1)%MAXQSIZE;//尾指针更新,+1%MAX=0
删除元素:
e=Q.base[Q.front];//把头指针所指元素赋值给某个变量e
Q.front=(Q.front+1)%MAXQSIZE;//头指针位置的变化
循环队列并不是一个圈,是想象而成的。
所以,循环队列:循环使用为队列分配的存储空间。
判断队空队满:少用一个元素空间
- 队空的条件:Q.front = Q.rear(队满也是,但无法区分,所以少用一个元素空间)
- 队满的条件:(rear+1)%MAXQSIZE = Q.front
二、循环队列基本操作
循环队列初始化
Status InitQueue(SqQueue &Q){
Q.base=new Qelemtype[MAXQSIZE] //分配数组空间,base是首元素,是数组的地址,所以前面定义为指针变量,用C++语法简单
//C语法:用malloc函数
if(Q.base)
exit(OVERFLOW); //存储分配失败
Q.front=Q.rear=0; //头尾指针置为0,队列为空
return OK;
}
循环队列的操作——求队列长度
int Qlength(SqQueue Q){
return ((Q.rear-Q.front+MAXQSIZE)%MAXQSIZE);
循环队列入队
Status EnQueue(SqQueue &Q,int e){
if((Q.rear+1)%MAXQSIZE==Q.front)//队满
return ERROR;
Q.base[Q.rear]=e; //把值赋给尾指针所指空间
Q.rear=(Q.rear+1)%MAXQSIZE;//尾指针更新,+1%MAX=0
return OK;
循环队列出队
Status DeQueue(SqQueue &Q,int &e){
if(Q.front==Q.rear) //队空
return ERROR;
e=Q.base[Q.front]; //保存队头元素
Q.front=(Q.front+1)%MAXQSIZE; //队头指针+1
return OK;
}
循环队列取队头元素
int GetHead(SqQueue Q){
if(Q.front!=Q.rear) //队列不为空
return Q.base[Q.front]; //返回队头指针元素的值,队头指针不变
三、循环队列简单实现
#include<bits/stdc++.h>
using namespace std;
const int MAXQSIZE=10;
typedef struct{
int *base;
int front;
int rear;
}SqQueue;
bool InitQueue(SqQueue &Q){
Q.base=new int[MAXQSIZE];
if(!Q.base)
exit(false);
Q.front=Q.rear=0;
return true;
}
int Qlength(SqQueue Q){
return ((Q.rear-Q.front+MAXQSIZE)%MAXQSIZE);
}
bool EnQueue(SqQueue &Q,int e){
if((Q.rear+1)%MAXQSIZE==Q.front)//队满
return false;
Q.base[Q.rear]=e; //把值赋给尾指针所指空间
Q.rear=(Q.rear+1)%MAXQSIZE;//尾指针更新,+1%MAX=0
return true;
}
bool DeQueue(SqQueue &Q,int &e){
if(Q.front==Q.rear) //队空
return false;
e=Q.base[Q.front]; //保存队头元素
Q.front=(Q.front+1)%MAXQSIZE; //队头指针+1
return true;
}
int GetHead(SqQueue Q){
if(Q.front!=Q.rear) //队列不为空
return Q.base[Q.front]; //返回队头指针元素的值,队头指针不变
}
int main()
{
int n;
SqQueue Q;
cout<<"循环队列基本操作:"
<<"1、循环队列初始化\n"
<<"2、入队\n"
<<"3、求队列长度\n"
<<"4、取队头元素\n"
<<"5、出队\n" ;
while(1){
cout<<"输入操作序号:";
cin>>n;
switch(n)
{
case 1: if(InitQueue (Q))
cout<<"循环队列初始化成功"<<endl;
else
cout<<"初始化失败";
break;
case 2:
for(int i=0;i<=10;i++)
EnQueue(Q,i);
cout<<"入队成功"<<endl; break;
case 3:
cout<<"队列长度为"<<Qlength(Q)<<endl; break;//输出是9,因为队尾指针一开始变为1
case 4:
cout<<" 队头元素为:"<<GetHead(Q)<<endl;break;
case 5:
cout<<"出队,队列元素为:";
for(int i=0;i<10;i++)
{
DeQueue(Q,i);
cout<<i<<" ";
}
cout<<endl;break;
}
}
}
内容参考:
《数据结构》严蔚敏
青岛大学——王卓