@Adrian
链式队列的实现思想同顺序队列类似,只需创建两个指针(命名为 top 和 rear)分别指向链表中队列的队头元素和队尾元素,如图 1 所示:
图 1 所示为链式队列的初始状态,此时队列中没有存储任何数据元素,因此 top 和 rear 指针都同时指向头节点。
链式队列数据入队
链队队列中,当有新的数据元素入队,只需进行以下 3 步操作:
- 将该数据元素用节点包裹,例如新节点名称为 elem;
- 与 rear 指针指向的节点建立逻辑关系,即执行 rear->next=elem;
- 最后移动 rear 指针指向该新节点,即 rear=elem;
由此,新节点就入队成功了。
链式队列数据出队
链式队列中队头元素出队,需要做以下 3 步操作:
- 通过 top 指针直接找到队头节点,创建一个新指针 p 指向此即将出队的节点;
- 将 p 节点(即要出队的队头节点)从链表中摘除;
- 释放节点 p,回收其所占的内存空间;
完整代码示例:
#include <stdio.h>
#include <stdlib.h>
//链表中的结点结构
typedef struct QNode{
int data;
struct QNode * next;
}QNode;
//创建链式队列的函数
QNode * initQueue(){
//创建头结点
QNode*queue=(QNode*)malloc(sizeof(QNode));
//对头结点进行初始化
queue->next=NULL;
return queue;
}
//数据入队
QNode*enQueue(QNode*rear,int data){
//1、用节点包裹入队元素
QNode*enElem=(QNode*)malloc(sizeof(QNode));
enElem->data=data;
enElem->next=NULL;
//2、新节点与rear节点建立逻辑关系
rear->next=enElem;
//3、rear指向新节点
rear=enElem;
//返回新的rear,为后续新元素入队做准备
return rear;
}
//数据出队
QNode*DeQueue(QNode*top,QNode*rear){
if(top->next==NULL){
printf("\n队列为空!");
return rear;
}
//1、
QNode*p=top->next;
printf("%d ",p->data);
top->next=p->next;
if(rear==p){
rear=top;
}
free(p);
return rear;
}
int main()
{
QNode * queue,*top,*rear;
queue=top=rear=initQueue();//创建头结点
//向链队列中添加结点,使用尾插法添加的同时,队尾指针需要指向链表的最后一个元素
rear=enQueue(rear, 1);
rear=enQueue(rear, 2);
rear=enQueue(rear, 3);
rear=enQueue(rear, 4);
//入队完成,所有数据元素开始出队列
rear=DeQueue(top,rear);
rear=DeQueue(top,rear);
rear=DeQueue(top,rear);
rear=DeQueue(top,rear);
rear=DeQueue(top,rear);
return 0;
}