队列(Queue)是只允许在一端进行插入,而在另一端进行删除的运算受限的线性。
- 允许删除的一端称为队头(Front)。
- 允许插入的一端称为队尾(Rear)。
- 当队列中没有元素时称为空队列。
- 队列亦称作先进先出(First In First Out)的线性表,简称为FIFO表。
- 队列的修改是依先进先出的原则进行的。新来的成员总是加入队尾(即不允许"加塞"),每次离开的成员总是队列头上的(不允许中途离队),即当前"最老的"成员离队。
#define MAXSIZE 100 //队列的最大长度
typedef struct
{
QElemType *base; //存储空间的基地址
int front; //头指针
int rear; //尾指针
}SqQueue;
例:
typedef struct
{
int* base;
int front;
int rear;
}SeQueue;
【算法步骤】
- 为队列分配一个最大容量为MAXSIZE的数组空间,base指向指针空间的首地址。
- 将头指针和尾指针置为0,表示队列为空。
【算法描述】
Status InitQueue(SqQueue &Q)
{//构建一个空队列
Q.base = new QElemType(MAXSIZE); //为队列分配一个最大容量为MAXSIZE的数组空间
if(!Q.base)
{
exit(OVERFLOW); //存储空间分配失败
}
Q.front = Q.rear = 0; //将头指针和尾指针置为0,队列为空
return OK;
}
例:
int InitQuene(SeQueue& q)
{
q.base = (int*)malloc(MAXSIZE * sizeof(int)); //动态分配内存
if (!q.base)
{
return false;
}
q.front = q.rear = 0;
return true;
}
【算法描述】:
int QueueLenght(SqQueue)
{
retturn (Q.rear - Q.front + MAXSIZE) % MAXSIZE; //对循环队列,
}
例:
//求循环队列长度
int QueueLength(SeQueue q)
{
return (q.rear - q.front + MAXSIZE) % MAXSIZE;
}
【算法步骤】:
- 判断队列是否满,若满则返回ERROR
- 将新元素插入队尾
- 队尾指针加1
【算法描述】:
//入队
Status EnQueue(SeQueue& q, QElemType e)
{ //插入元素e为Q的新队尾元素
if ((q.rear + 1) % MAXSIZE == q.front) //若尾指针在循环意义上加1后等于头指针,表明队满
{
return ERROR;
}
q.base[q.rear] = e; //新元素插入队尾
q.rear = (q.rear + 1) % MAXSIZE; //队尾指针加1
return OK;
}
例:
//入队
int EnQueue(SeQueue& q, int e)
{
if ((q.rear + 1) % MAXSIZE == q.front)
{
return false;
}
q.base[q.rear] = e;
q.rear = (q.rear + 1) % MAXSIZE;
return true;
}
【算法步骤】:
- 判断队列是否为空,若空则返回ERROR
- 保存队头元素
- 队头指针加1
【算法描述】:
//出队
Status DeQueue(SeQueue& q, QElemType& e)
{//删除q的队头元素,用e返回其值
if (q.front == q.rear) //队空
{
returnERROR;
}
e = q.base[q.front]; //保存队头元素
q.front = (q.front + 1) % MAXSIZE; //队头指针加1
return OK;
}
例:
//出队
int DeQueue(SeQueue& q, int& e)
{
if (q.front == q.rear)
{
return false;
}
e = q.base[q.front];
q.front = (q.front + 1) % MAXSIZE;
return e;
}
当队列非空时,此操作返回当前队头元素的值,队头指针保持不变
【算法描述】:
//取队头元素
QElemType GetHead(SeQueue q)
{//返回q的队头元素,不修改会头指针
if (q.front != q.rear) //队列非空
{
return q.base[q.front]; //返回当前队头元素的值,队头指针保持不变
}
}
例:
//取队头元素
int GetHead(SeQueue q)
{
if (q.front != q.rear)
{
return q.base[q.front];
}
【算法描述】:
Status DesQueue( SqQueue *Q )
{
free( Q.base ) ;
Q.base = NULL ;
Q.front = Q.rear = 0 ;
return OK;
}
例:
int DesQueue( SqQueue *Q )
{
free( Q.base ) ;
Q.base = NULL ;
Q.front = Q.rear = 0 ;
return ture;
}
typedef struct QNode
{
QElemType data;
Struct QNode *next;
}QNode, *QueuePtr;
typedef struct
{
QueuePtr front; //队头指针
QueuePtr rear; //队尾指针
}LinkList;
例:
typedef struct QNode
{
int data;
Struct QNode *next;
}QNode, *QueuePtr;
typedef struct
{
QueuePtr front; //队头指针
QueuePtr rear; //队尾指针
}LinkQueue;
【算法步骤】:
- 生成新节点作为头节点,队头和队尾指针指向此节点
- 头节点的指针域置空
【算法描述】:
Status InitQueue(LinkQueue &Q)
{ //构造一个空队列Q
Q.front = Q.rear = new QNode; //生成新节点作为头节点,队头和队尾指针指向此节点
Q.front->next = NULL; //头节点的指针域置空
return OK;
}
例:
int InitQueue(LinkQueue &Q)
{
Q.front = Q.rear = (QNode*)mallco(sizeof(QNode)); //生成新节点作为头节点,队头和队尾指针指向此节点
Q.front->next = NULL; //头节点的指针域置空
return true;
}
【算法步骤】:
- 为入队元素分配节点空间,用指针p指向。
- 将新节点数据域置为e。
- 将新节点插入到队尾。
- 修改队尾指针为p。
如图:
**【算法描述】:**Staus EnQueue (LinkQueue &Q, QElemTpye e)
{//插入元素e为Q的新队尾元素
p = new QNode; //为入队元素分配节点空间,用指针p指向
p->data = e; //将新节点的数据域置为e
p->next = NULL; //将新节点插入队尾
Q.rear->next = p; //修改队尾指针
Q.rear = p;
return OK;
}
例:
int EnQueue (LinkQueue &Q, int e)
{//插入元素e为Q的新队尾元素
p = (QNode *)malloc(sizeof(QNode)); //为入队元素分配节点空间,用指针p指向
p->data = e; //将新节点的数据域置为e
p->next = NULL; //将新节点插入队尾
Q.rear->next = p; //修改队尾指针
Q.rear = p;
return true;
}
【算法步骤】:
- 判断队列是否为空,若空则返回ERROR
- 临时保存队头元素的值,以释放空间
- 修改队头节点的指针域,指向下一个节点
- 判断出队元素是否为最后一个元素,若是,则将队尾指针重新赋值,指向头节点
【算法描述】:
Status DeQueue(LinkQueue &Q, QElemType &e)
{//删除Q的队头元素,用e返回其值
if(Q.front == Q.rear) //若队列为空,则返回ERROR
{
return 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); //释放原队头元素的空间
return OK;
}
例:
int DeQueue(LinkQueue &Q, int &e)
{//删除Q的队头元素,用e返回其值
if(Q.front == Q.rear) //若队列为空,则返回ERROR
{
return false;
}
p = Q.front->next; //p指向队头元素
e = p->data; //e保存队头元素的值
Q.front->next = p->next; //修改头节点的指针域
if(Q.rear == p) //最后一个元素被删, 队尾指针指向头节点
{
Q.rear = Q.front;
}
delete(p); //释放原队头元素的空间
return true;
}
【算法描述】:
QElemType GetHead(LinkQueue Q)
{//返回Q的队头元素,不修改队头指针
if(Q.front != Q.rear) //队列非空
{
return Q.front->next->data; //返回队头元素的值,队头指针不变
}
}
例:
int GetHead(LinkQueue Q)
{//返回Q的队头元素,不修改队头指针
if(Q.front != Q.rear) //队列非空
{
return Q.front->next->data; //返回队头元素的值,队头指针不变
}
}
【算法描述】:
Status DesQueue( SqQueue *Q )
{
free( Q->base ) ;
Q->base = NULL ;
Q->front = Q->rear = 0 ;
return OK;
}
例:
int DesQueue( SqQueue *Q )
{
free( Q->base ) ;
Q->base = NULL ;
Q->front = Q->rear = 0 ;
return ture;
}