二十三、队列的表示和操作的实现
- 相关术语
- 队列是仅在表尾进行插入操作,在表头进行删除操作的线性表
- 表尾既a~n段,称对尾;表头a~1段,称队头
- 它是一种先进先出(FIFO)的线性表
- 入队:插入元素
- 出队:删除元素
- 队列的存储结构为链对或顺序对(常用循环顺序队)
- 队列的常见应用
- 脱机打印输出:按申请的先后顺序依次输出
- 多用户系统中,多个用户排成队,分时循环使用cpu和主存
- 按用户的优先级排成多个队,每个优先级一个队列
- 实时控制系统中,信号按接收的先后顺序依次处理
- 网络电文传输,按到达的时间先后顺序依次进行
队列的顺序表示和实现
- 队列的物理存储可以用顺序存储结构,链式存储结构,队列的存储方式有两种,顺序队列和链式队列
- 队列的顺序表示——用一维数组base[MAXQSIZE]
#define MAXQSIZE 100 //最大队列长度
Typedef struct
{
QElemType *base; //初始化的动态分配存储空间
int front; //头指针
int rear; //尾指针
}SqQueue;
- 队列问题
- 若数组大小为MAXQSIZE
- rear=MAXQSIZE,发生溢出
- front=0,rear=MAXQSIZE,再入队——真溢出
- front=-,rear=MAXQSIEZE,在入队——假溢出
- 解决假上溢方法
- 将队中元素依次相对头方向移动
- 缺点
- 浪费时间,每移动依次,对中元素都要移动
- 缺点
- 将队中元素依次相对头方向移动
- 若数组大小为MAXQSIZE
- 引用循环队列
- 将对空间想象成一个循环的标,分配给队列m个存储单元循环使用,当rear是maxqsize时,向量的开始端空着,从头使用空着的空间,front为maxqsize,一样
- base[0]接在base[MAXQSIZE-1]后,若rear+1==M,令rear=0;
- 利用模运算(mod,求余)
- 插入元素
- Q.base[Q.rear]=x
- Q.rear=(Q.rear+1)%MAXQSIZE
- 删除元素
- x=Q.base[s.front]
- Q.front=(Q.front+1)%MAXQSIZE
- 插入元素
- 出现队空堆满都是front==rear
- 解决方案
- 再设一个标志区别
- 再设一个变量,记录元素个数
- 少用一个元素空间
- 队空:front==rear
- 队满:(rear+1)%MAXQSIZE==front
- 解决方案
- 循环队列类型定义
- 队列初始化
Status InitQueue(SqQueue &Q)
{
Q.base=new QElemType[MAXQSIZE] //分配数组空间 //Q.base=(QElemType *) malloc(MAXQSIZE*sizeof(QElemType));
if(!Q.base)
exit(OVERFLOW); //存储分配失败
Q.front=Q.rear=0; //头指针尾指针为0,队列为空
return OK;
}
- 求循环队列长度
int QueueLength(SqQueue Q)
{
return((Q.rear-Q.front+MAXQSIZE)%MAXQSIZE);
}
- 循环队列入队
Status EnQueue(SqQueue &Q,QElemType e)
{
if((Q.rear+!)%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)
{
if(Q.front==Q.rear)
reutn ERROR; //对空
e=Q.base[Q.front]; //保存队头元素
Q.front=(Q.front+1)%MAXQSIZE //队头指针+1
return OK;
}
- 取队头元素
SElemType GetHead(SqQuere Q)
{
if(Q.front!=Q.rear)
return Q.base[Q.front]; //返回指针元素的值,队头指针不变
}
- 队列的链式存储结构
- 用户无法估计所用队列长度,采用链队列
- 链队列的类型定义
#define MAXQSIZE 100 //最大队列长度
typedef struct Qnode
{
QElemType data;
stuct Qnode *next;
}QNode,*QuenePtr;
- 链队列初始化
Status InitQueue(LinkQueue &Q)
{
Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
if(!Q.front)
exit(OVERFLOW);
Q.front->next=NULL;
reutrn OK;
}
- 销毁队列
Status DestroyQueue(LinkQueue &Q)
{
while(Q.front)
{
p=Q.front->next;
free(Q.front);
Q.front=p
}
return OK;
}
- 链队列元素入队
Status EnQueue(LinkQueue &Q,QElemType e)
{
p=(QueuePtr)malloc(sizeof(QNode));
if(!p)
exit(OVERFLOW);
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
return OK;
}
- 链队列元素出队
Status DeQueue(LinkQueue &Q,QElemType &e)
{
if(Q.front==Q.rear)
return ERROR;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p)
Q.rear=Q.front;
delete p;
return OK;
}
- 链队列的类型定义
#define MAXQSIZE 100 //最大队列长度
typedef struct Qnode
{
QElemType data;
stuct Qnode *next;
}QNode,*QuenePtr;