构造队列的初始套路是:定义队列参数结构体,参数赋值成空队列特征
链队列前言:
链队列参数:front,rear
front指向头节点,rear指向队尾
1, 定义一个队列(参数结构体)
2, 分配头节点,front和rear指向头节点,即空队列
空队列是可描述的:front== rear ==头节点
思考:为什么要引入头节点,而不是front = rear = NULL?
答:如果没有头节点,第一次入队需要修改front,最后一个节点出队,需要修改rear,麻烦!
顺序队列前言:
顺序队列参数:base,front,rear
base 初始队列容量的基址,用于操作各个队列元素
front指向队头(有效元素),rear指向队尾元素的下一个空位
1, 定义一个队列(参数结构体)
2, 分配一定空间的连续存储空间
3, front = rear = 0;
重要概念:
顺序队列要是循环队列,不然会随着出队入队造成空间的浪费。
如何实现空间的循环利用?
答:N个连续的存储单元,第一个单元编号是0,最后一个单元是N-1;
i代表任意一个单元的编号,++i % N能实现i的值从0走到N-1再自动回到0,依次循环往复。
空队列:front = rear
队满:(rear + 1)% N = front
难点:怎样通过rear和front计算队列元素的个数。
链队列C代码:
typedef struct Node
{
ElemType data;
struct Node* next;
}QNode;//结点包括指针域和数据域
typedef struct
{
QNode* front;
Qnode* rear;
}Queue;//队列参数
Status InitQueue(Queue*Q)
{
(*Q).front = (*Q).rear = (QNode*)malloc(sizeof(QNode));
if(!(*Q).front)
exit(-1);
(*Q).front->next = NULL;
return ok;
}//初始化,空队列
Status DestoryQueue(Queue*Q)
{
while((*Q).front)
{
(*Q).rear = (*Q).front->next;
free((*Q).front);
(*Q).front = (*Q).rear;
}
return ok;
}
Status ClearQueue(Queue*Q)
{
QNode*q,*p;
(*Q).rear = (*Q).front;//都指向头节点
p = (*Q).front->next;
(*Q).front->next = NULL;//头节点指针域为空
while(p)
{
q = (*p).next;
free(p);
p = q;
}
return ok;
}
Status QueueEmpty(Queue Q)
{
return ((Q).front==(Q).rear)?true:false;
}
int QueueLength(Queue Q)
{
int i = 0;//计数器
while(Q.front!=Q.rear)
{
++i;
Q.front = Q.front->next;
}
return i;
}
Status EnQueue(Queue*Q,ElemType e)
{
QNode* p = (QNode*)malloc(sizeof(QNode));
if(!p)
exit(-1);
(*p).data = e;
(*p).next = NULL;
(*Q).rear->next = p;
(*Q).rear = p;
return ok;
}
Status DeQueue(Queue*Q,ElemType* e)
{
QNode* p;
if(QueueEmpty(*Q))
return error;//非空队列才能出队列
p = (*Q).front->next;
*e = p->data;
(*Q).front->next = p->next;
if(p==(*Q).rear)//出队可能改变谁是队尾,要更新参数
(*Q).rear = (*Q).front;
free(p);
p = NULL;
return ok;
}
void TraverseQueue(Queue Q)
{
if(QueueEmpty(Q))
return error;
QNode* p = Q.front->next;
while(p!=Q.rear)
{
printf("%d ",p->data);
p = p->next;
}
printf("%d\n",Q.rear->data);
}
/*顺序队列C代码
顺序队列也叫循环队列,之所以循环,是为了避免由于入队和出队
过程造成的空间浪费,使空间循环利用*/
typedef struct
{
ElemType* base;//操控每个元素
int front;//队头
int rear;//队尾
}SqQueue;//顺序队列参数
Status InitSqQue(SqQueue*Q)
{
(*Q).base = (ElemType*)malloc(sizeof(ElemType)*MAXSIZE);
if(!(*Q).base)//分配队列容量
exit(-1);
(*Q).front = (*Q).rear = 0;//空队列
return ok;
}
Status ClearSqQue(SqQueue*Q)
{
(*Q).front = (*Q).rear = 0;
return ok;//恢复初始化状态即为空队列
}
Status SqQueEmpty(SqQueue Q)
{
return Q.front==Q.rear?true:false;
}
Status SqQueFull(SqQueue Q)
{
return (Q.rear+1)%MAXSIZE == Q.front?true:false;
}
int SqQueLength(SqQueue Q)
{
return (Q.rear-Q.front+MAXSIZE)%MAXSIZE;
}
Status EnSqQue(SqQueue*Q,ElemType e)
{
if(SqQueFull(*Q))
return error;//队列不能满才能入队
(*Q).base[(*Q).rear] = e;
(*Q).rear = ((*Q).rear+1)%MAXSIZE;
return ok;
}
Status DeSqQue(SqQueue*Q,ElemType*e)
{
if(SqQueEmpty(*Q))
return error;//队列不空才能出队
*e = (*Q).base[(*Q).front];
(*Q).front = ((*Q).front+1)%MAXSIZE;
return ok;
}
Status TraverseSqQue(SqQueue Q)
{
if(SqQueEmpty(Q))
return error;
while(Q.front!=Q.rear)
{
printf("%d ",Q.base[Q.front]);
Q.front = (Q.front+1)%MAXSIZE;
}
printf("\n");
return ok;
}