队列:队列是仅在表尾进行插入操作,在表头进行删除操作的线性表。
表尾即an端,称为队尾,表头即a1端,称为队头。
队列的存储方式:顺序队列和链式队列
队列顺序表示
#define MAXQSIZE 100 //最大队列长度
Typedef struct{
QElemType *base;
int front; //头指针
int rear; //尾指针
}SqQueue;
设数组大小为MAXQSIZE
则当rear = MAXQSIZE时,发生溢出,这里分为两种情况:真溢出和假溢出。
如下图所示:
解决假上溢的方法——引入循环队列
实现方法:利用模(mod,取余)运算
插入元素时:Q.base[Q.rear]=x; Q.rear=(Q.rear+1)%MAXQSIZE;
删除元素时:x=Q.base[Q.front]; Q.front=(Q.front+1)%MAXQSIZE;
这里的循环队列指的是循环使用为队列分配的存储空间。
**问题:**在循环队列中,队空和队满的条件都是:front=rear
要怎么区分这两者呢?
解决方案如下:
循环队列的操作——队列的初始化
Status InitQueue(SqQueue &Q){
Q.base=new QElemType[MAXQSIZE] //分配数组空间
if(!Q.base) exit(OVERFLOW);
Q.front=Q.rear=0;
return OK;
}
循环队列的操作——队列长度
int QueueLength(SqQueue Q){
return((Q.rear-Q.front+MAXQSIZE)%MAXQSIZE);
}
循环队列的操作——队列入队
Status EnQueue(SqQueue &Q,QElemType e){
if((Q.rear+1)%MAXQSIZE==Q.front) return ERROR; //队满
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQSIZE;
return OK;
}
循环队列的操作——队列出队
Status DeQueue(SqQueue &Q,QElemType &e){
if(Q.front==Q.rear) return ERROR;
e=Q.base[Q.front]; //保存队头元素
Q.front=(Q.front+1)%MAXQSIZE;
return OK;
}
循环队列的操作——取队头元素
SElemType GetHead(SqQueue Q){
if(Q.front!=Q.rear)
return Q.base[Q.front]; //返回队头指针元素的值,队头指针不变
}
队列的链式表示和实现
类型定义
# define MAXQSIZE 100
typedef struct Qnode{
QElemType data;
struct Qnode *next;
}Qnode,*QueuePtr;
链队列初始化
Status InitQueue(LinkQueue &Q){
Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode)); //队头,队尾指针均指向初始化结点。
if(!Q.front) exit(OVERFLOW);
Q.front->next=NULL;
return OK;
}
销毁链队列
思路:从队头结点开始,依次释放所有结点
Status DestroyQueue(LinkQueue &Q){
while(Q.front){
p=Q.front->next;
free(Q.front);
Q.front=p;
}
return OK;
}
插入元素e
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;
}
获取链队列的队头元素
Status GetHead(LinkQueue Q,QElemType &e){
if(Q.front==Q.rear) return ERROR;
e=Q.front->next->data;
}