队列
操作受限的线性表
一端进行插入,一端删除------>比如食堂排队打饭,队尾插入,队头离开
特性:先进先出(FIFO)First In First Out
顺序方式实现队列
定义
#define MaxSize 10 //定义队列中元素最大个数
typedef struct{
ElemType data[MaxSize];
int front,rear; //队头指针和队尾指针
}SqQueue;
void testQueue(){
SqQueue Q; //声明一个队列(顺序存储)
}
初始化
//初始化一个空队列,让队头指针和队尾指针指向0
bool InitQueue(SqQueue &Q){
Q.front=Q.rear=0;
}
//入队操作时,数据插入到队尾指针所在的区域,队尾指针后移
//出队操作时,若队非空,先取对头指针所在区域的位置,然后队头指针加1
判空
bool QueueEmpty(SqQueue Q){
if(Q.rear==Q.front)
return true;
else
return false;
}
入队
//入队操作
bool EnQueue(SqQueue &Q,ElemType x){
//判断队列是否满
if((Q.rear+1)%MaxSize==Q.front)
return false;
//未满进行入队
Q.data[Q.rear]=x;
Q.rear=(Q.rear++)%MaxSize;
return true;
}
/*判断队满的条件,因为出队时队头指针后移,所以前面部分又空了,因此可以循环的进行入队操作,当队尾指针指到MaxSize-1的时候,入队操作后进行取余运算,则又回到了0位置,若队头指针也在这里,说明队满了。*/
出队
//删除一个队头元素,并用x返回
bool DeQueue(SqQueue &Q,ElemType &x){
//判断队列是否为空
if(Q.rear==Q.front)
return false;
x=Q.data[Q.front];
Q.front=(Q.front+1)%MaxSize; //对头指针后移
return true;
}
获取队头元素
bool GetHead(SqQueue &Q,ElemType &x){
//判断队列是否为空
if(Q.rear==Q.front)
return false;
x=Q.data[Q.front];
return true;
}
判断队满:队尾指针的后一个等于队头指针
判断队空:队尾指针等于队头指针
计算当前队列中元素的个数:(rear+MaxSize-front)%MaxSize
链式方式实现队列
定义
typedef struct { //链式队列结点
ElemType data;
struct LinkNode *next;
}LinkNode;
typedef struct{ //链式队列
LinkNode *front,*rear; //队头执指针和队尾指针
}LinkQueue;
初始化
//带头节点
bool InitQueue(LinkQueue &Q){
Q.front=Q.rear=(LinkNode *)malloc(sizeof(LonkNode));
Q.front->next=NULL;
}
//不带头节点
bool InitQueue(LinkQueue &Q){
Q.front=Q.rear=NULL;
}
判空
//判空,带头节点
bool EmptyQueue(LinkQueue Q){
if(Q.front->next==NULL)
return true;
else
return false;
}
//不带头节点
bool EmptyQueue(LinkQueue Q){
if(Q.front==NULL)
return true;
else
return false;
}
入队
//入队,带头结点
bool EnQueue(LinkQueue &Q,ElemType x){
//声明一个新的节点
LinkNode *p=(LinkNode *)malloc(sizeof(LinkNode));
p->data=x;
p->next=NULL; //队尾插入
Q.rear->next=p;
Q.rear=p;
return true;
}
//入队,不带头节点
bool EnQueue(LinkQueue &Q,ElemType x){
//声明一个新的节点
LinkNode *p=(LinkNode *)malloc(sizeof(LinkNode));
p->data=x;
p->next=NULL;
//如果之前是空队列,则头指针和尾指针都要修改,若不是,则不需要修改头指针
if(Q.front==NULL){
Q.front=Q.rear=p;
}else
{
Q.rear->next=p;
Q.rear=p;
}
return true;
}
出队
//出队,带头结点
bool DelQueue(LinkQueue &Q,ElemType &x){
//判断是否为空队列
if(Q.front->next==NULL)
return false;
LinkNode *p=Q.front->next;
Q.front->next=p->next;
if(Q.rear==p){ //若刚好为尾结点,则需要修改尾节点指向头结点
//Q.front->next=p->next;
Q.rear=Q.front;
//free(p);
}else{
//Q.front->next=p->next;
//free(p);
}
free(p);
return true;
}
//出队,不带头节点
bool DelQueue(LinkQueue &Q,ElemType &x){
//判断是否为空队列
if(Q.front==NULL)
return false;
LinkNode *p=Q.front;
x=p->data;
Q.front=p->next;
if(Q.rear==p){ //若为尾节点,则修改为NULL
Q.rear=Q.front=NULL;
}
free(p);
return true;
}
双端队列
操作受限的线性表
只允许两端插入,两端删除的线性表