队列的存储结构
队列是只允许在一端进行插入操作,在另一端进行删除操作的线性表,即“先进先出”
typedef struct QNode
{
int data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct
{
QueuePtr front,rear;
}LinkQue,*LinkQueue;
结点由存放数据元素的数据域和存放放后继结点地址的指针域组成
链队列由指向头结点的front和指向队尾的rear组成
同线性表,元素具有相同的类型,相邻元素具有前驱和后继关系。
一、队列的初始化操作
目的:初始化队列
实现:类比链表创建头结点,让front和rear都指向头结点,初始化一个空队列
void InitQueue(LinkQueue &Q)
{
Q=(LinkQueue)malloc(sizeof(LinkQue));
QueuePtr s=(QueuePtr)malloc(sizeof(QNode));
Q->front=s;
Q->rear=s;
}
二、队列的相关函数
判断队列是否为空
若队列为空返回true,否则返回false
bool QueueEmpty(LinkQueue Q)
{
return Q->rear==Q->front;
}
获得队列的长度
创建结点指针s遍历链队列,返回队列长度
int QueueLength(LinkQueue Q)
{
int len=0;
QueuePtr s=Q->front;
while (s->next)
{
s=s->next;
len++;
}
return len;
}
三、获得获得队列头元素
功能:输出获得队列头元素
实现:先判断队列是否为空,非空则输出队头(即头结点后的第一个元素的数据)
void GetHead(LinkQueue Q)
{
if (QueueEmpty(Q))
{
cout<<"队列为空!"<<endl;
return ;
}
cout<<"队列头元素是:"<<Q->front->next->data<<endl;
}
四、队列的插入
功能:插入e到队头
实现:①对创建的结点s赋值,使s的next为空
②将s入队,当前队尾的next指向s,并使s成为新的队尾
void EnQueue(LinkQueue Q,int e)
{
QueuePtr s=(QueuePtr)malloc(sizeof(QNode));
if(!s) cout<<"error!"<<endl;
s->data=e;
s->next=NULL;
Q->rear->next=s;
Q->rear=s;
cout<<"插入数据:"<<e<<"成功!"<<endl;
}
链队列插入数据的方式类似于链表的尾插法
五、队列的删除
功能:删除队列头元素
实现:①判断是否为空,非空则输出队列头元素
②使头结点的next跳过原来的队头,指向新的队头
③释放原来的队头
void DeQueue(LinkQueue Q)
{
if (QueueEmpty(Q))
{
cout<<"队列为空!"<<endl;
return ;
}
QueuePtr p;
p=Q->front->next;
int e=p->data;
Q->front->next=p->next;
if (Q->rear==p)
{
Q->rear=Q->front;
}
free(p);
cout<<"删除数据"<<e<<"成功!"<<endl;
}
还要判断删除的元素是否是队列的最后一个元素,如果是,添加满足空队列的条件front和rear都指向头结点
六、清空队列
功能:将队列清空
实现:只要队列不为空就不断删除队头即可
void ClearQueue(LinkQueue Q)
{
while (!QueueEmpty(Q))
{
DeQueue(Q);
}
}
七、销毁队列
功能:将队列销毁
实现:清空队列后释放头结点的内存空间,达到彻底销毁的目的
void DestroyQueue(LinkQueue Q)
{
ClearQueue(Q);
free(Q);
}
这里可以看到销毁之后的cr指针指向的内存空间已经被释放,而清空之后的Q仍指向创建的队列内存
总结
本篇介绍了使用链式结构创建队列并进行插入删除元素等操作
测试代码及运行实例
int main()
{
LinkQueue Q,cr;
InitQueue(Q);
InitQueue(cr);
for (int i = 0; i < 10; i++)
{
EnQueue(Q,i+1);
EnQueue(cr,i+1);
GetHead(Q);
}
cout<<"队列的长度为"<<QueueLength(Q)<<endl;
for (int i = 0; i < 10; i++)
{
DeQueue(Q);
GetHead(Q);
}
ClearQueue(cr);
GetHead(cr);
DestroyQueue(cr);
GetHead(cr);
return 0;
}