一、队列的定义
队列,是一种操作受限的线性表,只允许在表的一侧进行插入,在另一端进行删除。数据先进先出
二、队列的顺序存储结构
1.队伍的顺序存储
存储类型描述:
typedef struct{
ElemType data[Maxsize];
int front, rear;
}SQueue;
front指向队首,rear指向队尾。
初始时:Q.front=Q.rear=0。
入队:不满时,先赋值,再加1。
出队:非空时,先取值,再加1。
空队
五个元素入队
出队一次
出队三次
如上图所示,
队列中仅有一个元素,但Q.rear==Maxsize,无法继续入队,这种情况称为“上溢出”;像这种溢出而非真正的溢出,数组中仍有可以存放元素的空位置的情况,称为“假溢出”。
2.顺序队列
为避免上述“假溢出”的问题,这里引入循环队列的概念。循环队列并非物理意义上的循环,而是当指针到达Maxsize-1后,再前进一个位置就自动到0,从而实现逻辑上的循环,这里可以利用取余(%)来实现。
初始时:
Q.front = 0;
Q.rear = 0;
指针进1:
Q.front = (Q.front + 1) % Maxsize;
Q.rear = (Q.rear + 1) % Maxsize;
队伍长度:
Length = (Q.rear + Maxsize - Q.front) % Maxsize;
判断队空/队满:
队空时:
Q.front == Q.rear;
队满时:
1)牺牲一个存储单元:
(Q.rear + 1) % Maxsize == Q.front;
2)增设size数据成员,记录队列元素个数:
Q.size == Q.maxsize;
3)增设tag数据成员,判断区分队空还是队满(队空的上一步一定是出队,队满的上一步一定是入队),初始时,tag=0,入队成功时,tag=1;出队成功时,tag=0。当Q.front == Q.rear时,判断tag,若tag=0,则队空,反之队满。
3.循环队列的基本操作
1)初始化
void Init(SQueue& Q)
{
Q.rear = 0;
Q.front = Q.rear;
}
2)判空
bool Empty(SQueue Q)
{
if (Q.rear == Q.front)
return true;
else return false;
}
3)入队
bool EnQueue(SQueue& Q,ElemType e)
{
if ((Q.rear + 1) % Maxsize == Q.front)
return false;
Q.data[Q.rear] = e;
Q.rear = (Q.rear + 1) % Maxsize;
return true;
}
4)出队
bool DeQueue(SQueue& Q, ElemType e)
{
if (Empty(Q))
return false;
e = Q.data[Q.front];
Q.front = (Q.front + 1) % Maxsize;
return true;
}
三、队列的链式存储
1.链队列的定义
队列的链式存储,即链队列,实质上是指有队头指针和队尾指针的单链表:
其存储类型描述为:
typedef struct LinkNode{
ElemType data;
struct LinkNode* next;
}LinkNode;
typedef struct{
LinkNode *front,*rear;
}LinkQueue;
2.链队列的基本操作
1)初始化
void InitQueue(LinkQueue& Q)
{
Q.front = (LinkNode*)malloc(sizeof(LinkNode));
if (Q.front)
{
Q.rear = Q.front;
Q.front->next = NULL;
}
}
2)判空
bool EmptyQueue(LinkQueue Q)
{
if (Q.front == Q.rear)
return true;
else return false;
}
3)入队
void EnLinkQueue(LinkQueue& Q, ElemType e)
{
LinkNode* p = (LinkNode*)malloc(sizeof(LinkNode));
if (p)
{
p->data = e;
p->next = NULL;
Q.rear->next = p;
Q.rear = p;
}
}
4)出队
bool DeLinkQueue(LinkQueue& Q, ElemType e)
{
if (EmptyQueue(Q))
return false;
LinkNode* p = Q.front->next;
Q.front->next = p->next;
e = p->data;
if (p == Q.rear)
Q.rear = Q.front;
free(p);
return true;
}