队列的定义
队列(Queue)是只允许在一端进行插入(入队),在另一端进行删除(出队)的线性表。
重要术语:队头、对尾、空队列
队头:允许删除的一端(出队)
对尾:允许插入的一端(入队)
队列的特点:先进先出(FIFO)
队列的基本操作
队列的顺序实现
队列存储类型:
#define MaxSize 10
typedef struct{
ElemType data[MaxSize];
int front,rear; //标记队列队头和指针
}SqQueue;
//初始化
void Init_Queue(SqQueue &Q){
Q.front=Q.rear=0;
}
//判空
bool IsEmpty(SqQueue Q){
if(Q.front=Q.rear)
return true;
else
return false;
}
注意:队头指针和队尾指针初始都指向0
(其中队头指针指向队头元素;队尾指针指向是接下来插入数据元素的位置)
判断队是否为空:(Q.rea==Q.front)
循环队列
入队:
判断队满条件为:(Q.rea+1)%MaxSize==Q.front 是以牺牲一个队尾指针所指向的存储单元为代价。
出队、获取队头元素
队列元素个数:(rear+MaxSize-front)%MaxSize
方法二:
队列的链式实现
带头结点的队列不带头结点队列:
注意第一个元素入队和最后一个元素出队的情况。
//队列的链式实现
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode;
typedef struct{
LNode *front,*rear;
}LinkQueue;
初始化
void InitQueue(LinkQueue &Q){
//带头结点
LNode *head=(LNode*)malloc(sizeof(LNode));
Q->front=head;
Q->rear=head;
//不带头结点
Q->front=NULL;
Q->rear=NULL;
}
入队
//入队
void EnQueue(LinkQueue &Q,ElemType x){
LNode *s=(LNode*)malloc(sizeof(LNode));
//带头结点
s->data=x;
s->next=NULL;
Q.rear->next=s;
Q.rear=s;
//不带头结点
s->data=x;
s->next=NULL;
if(Q.front==NULL){ //若第一个元素入队将头指针和尾指针指向第一个元素
Q.front=s;
Q.rear=s;
}
else{
Q.rear->next=s;
Q.rear=s;
}
}
出队
bool DeQueue(LinkQueue &Q,ElemType &x){
//带头结点
if(Q.front==Q.rear) //空队
return false;
LNode *s=Q.front->next;
x=s->data;
Q.front->next=s->next;
if(Q.rear==s)
Q.rear=Q.front; //最后一个元素出队修改rear指针,使其也指向头结点
free(s);
return true;
//不带头结点
if(Q.front=NULL)
return false; //空队
LNode *s=Q.front;
x=s->data;
Q.front=s->next;
if(Q.rear=s){ //最后一个元素出队,修改front,rear指针指向NULL
Q.front=NULL;
Q.rear=NULL;
}
free(s);
return true;
}