与栈相反,队列是一种先进先出的线性表。它只允许在表的一端进行插入,而在另一端删除元素。
和线性表类似,队列也可以有两种存储表示。
用链表表示的队列简称链队列。下面是带头结点的单链队列的实现
#include <stdio.h>
#include <malloc.h>
typedef char QElemType;
//单链队列节点
typedef struct QNode
{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
//单链队列
typedef struct
{
QueuePtr front; //队头指针
QueuePtr rear; //队尾指针
}LinkQueue;
//初始化单链队列
void InitQueue(LinkQueue &Q)
{
Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
Q.front->next=NULL;
}
//销毁单链队列
void DestroyQueue(LinkQueue &Q)
{
while(Q.front)
{
Q.rear=Q.front->next;
free(Q.front);
Q.front=Q.rear;
}
}
//入队列
void EnQueue(LinkQueue &Q,QElemType e)
{
QueuePtr p=(QueuePtr)malloc(sizeof(QNode));
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
}
//出队列
bool DeQueue(LinkQueue &Q,QElemType &e)
{
if(Q.front==Q.rear)
return false;
QueuePtr p=Q.front->next;
e=p->data;
Q.front->next=p->next;
//如果队列只有一个元素
if(p==Q.rear)
Q.front=Q.rear;
free(p);
}
队列的顺序表示一般实现为循环队列。下面是循环队列的实现
因为Q.front=Q.rear不能区分队列是空还是满,所以下面采用少用一个元素空间来解决这个问题。
#include <stdio.h>
#include <malloc.h>
#define MAXQSIZE 100 //最大队列长度
typedef char QElemType;
//定义循环队列
typedef struct
{
QElemType *base; //
int front; //头指针,若队列非空,指向队列头元素
int rear; //尾指针,若队列非空,指向队列尾元素的下一个位置
}SqQueue;
//初始化
void InitQueue(SqQueue &Q)
{
Q.base=(QElemType *)malloc(MAXQSIZE*sizeof(QElemType));
Q.front=Q.rear=0;
}
//获取队列的长度
int QueueLength(SqQueue Q)
{
return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}
//入队列
bool EnQueue(SqQueue &Q,QElemType e)
{
//判断队列是否已经满了
if((Q.rear+1)%MAXQSIZE==Q.front)
return false;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQSIZE;
return true;
}
//出队列
bool DeQueue(SqQueue &Q,QElemType &e)
{
//判断队列是否为空
if(Q.rear==Q.front)
return false;
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
return true;
}