循环队列
1、顺序队列:使用一组地址连续的存储空间,依次存储。附设两个指针,分别指向队头和队尾
2、循环队列:将顺序队列臆造为一个环状的空间
性质
队空条件:front == rear
队满条件:(rear+1) %QueueSize == front
队列长度:(rear—front + QueueSize) % QueueSize
(1)队列初始化时,front和rear值都为零;
(2)当队列不为空时,front指向队列的第一个元素,rear指向队列最后一个元素的下一个位置;
(3)当队列为空时,front与rear的值相等,但不一定为零;
循环队列存储结构:
typedef struct {
QElemType *base;//基地址
int front;//头指针
int rear;//尾指针
}SqQueue;
循环队列初始化
void InitQueue(SqQueue &SQ)
{
SQ.base = (QElemType *)malloc(MAXSIZE * sizeof(QElemType));//给数组分配空间
if (!SQ.base)exit(-1);
SQ.front = SQ.rear = 0;//初始化下标都为0
}
求循环队列的长度
int SqQueueLength(SqQueue SQ)
{
return (SQ.rear - SQ.front + MAXSIZE) % MAXSIZE;
//考虑到的是,可能front不在0处,所以使用这种方式来取长度
}
循环队列插入元素
void EnSQueue(SqQueue &SQ, QElemType e) {
if (((SQ.rear + 1) % MAXSIZE) == SQ.front)exit(-1);
//如果队列已经满了,直接退出
SQ.base[SQ.rear] = e;//只需要移动尾部指针,把传入的值放在尾部
SQ.rear = (SQ.rear + 1) % MAXSIZE;//更替尾指针
}
删除元素
void DeSQueue(SqQueue &SQ,QElemType &e) {
if (SQ.front == SQ.rear)exit(-1);//如果队空,直接退出
e = SQ.base[SQ.front];//把被删除的元素给e
//在队头删除,所以只需要把队头元素给e
SQ.front = (SQ.front + 1) % MAXSIZE;
//之后front更替,front移到后面
}
判断空/取队头
Status GetHead(SqQueue Q)
{
return Q.base[Q.front];//队头下标:front
}
bool QueueEmpty(SqQueue Q)
{
if (Q.front == Q.rear)
//队空:头指针等于尾指针
return true;
return false;
}
遍历
void visit(QElemType e)
{
printf("%d\t", e);
}
void QueueTraverse(SqQueue Q, void(visit)(QElemType))
//把visit函数作为参数
{
printf("队列的元素:\n");
int i = Q.front;//使用变量接收,怕会改变原来的值
while (i != Q.rear)
{
visit(Q.base[i]);
i = (i + 1) % MAXSIZE;//指针更替,继续滑动
}
printf("\n");
}
清空/销毁
void ClearQueue(SqQueue &Q) {
Q.front = Q.rear = 0;//把头指针和尾指针同时指向默认位置
}
void DestroyQueue(SqQueue &Q){
while (Q.front != Q.rear)//当头指针还没有滑动到尾指针的时候
{
free(&Q.base[Q.front]);//free内存
Q.front = (Q.front + 1) % MAXSIZE;//指针更替往下滑动
}
}