目录
队列是指只允许在一端进行插入数据操作,在另⼀端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)的特点。本篇文章的队列以链表为基础进行创建
(一)队列的定义,初始化及创建结点
//队列的初始化
//我们先宏定义队列存储的数据类型
#define QueueDataType int //这里我们宏定义队列存储的数据类型为int
//这里定义队列的结点
typedef struct QueueNode
{
QueueDataType data;
struct QueueNode* next;
}QueueNode;
//为了方便队列的出队和入队我们要新定义一个结构体,里面装着头结点和尾结点的指针。
type struct Queue
{
QueueNode* phead;
QueueNode* ptail;
}Queue;
这里我们定义了队列的结点和管理整个队列的结构体。关于链表形式的数据结构我们往往要单独写封装一个函数来创建结点。
//封装一个函数,专门用来创建结点
//该函数的形参是一个数据类型,返回创建的结点的指针
QueueNode* BuyNewNode(QueueDataType val)
{
//动态向内存申请空间
QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
//防止使用创建结点失败返回的NULL指针
if (newnode == NULL)
{
perror("newnode malloc failed!");
exit(1);
}
//给创建好的结点初始化
newnode->data = val;
newnode->next = NULL;
//返回初始值
return newnode;
}
我们还需要初始化管理整个结点的那个结构体,就叫它队列吧
//初始化队列
void InitQueue(Queue* pq)
{
//检查是否为空指针
assert(pq);
pq->phead = NULL;
pq->ptail = NULL;
}
(二)入队和出队,以及取队头队尾的数据
入队就是从队伍的后面进去。根据这个原理我们直接写
//队列的入队(要在初始化队列之后)
//我们通过管理整个队列的那个结构体来进行操作
//所以这里我们接受那个结构体的形参
void QueuePush(Queue* pq, QueueDataType val)
{
//检查是不是空指针
assert(pq);
//我们可以通过pq来找到队伍的尾结点
//进行入队操作。如果队列为空
if (pq->phead == NULL)
{
pq->phead = pq->ptail = BuyNewNode(val);
}
else //如果队列不为空,则尾插到队尾
{
pq->ptail->next = BuyNewNode(val);
pq->ptail = pq->ptail->next;
}
}
在写出队之前我们先得写一个函数来检查队列是否为空,防止队列里没有数据
//判断队列是否为空,我们采用bool值
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->phead == NULL;
}
进行出队。
//队列的出队
void QueuePop(Queue* pq)
{
//检查队列是否为空
assert(!QueueEmpty(pq));
//如果队列只有一个元素
if (pq->phead == pq->ptail)
{
pq->phead = pq->ptail = NULL;
}
else
{
//定义一个新结点来保存出队后的头结点
QueueNode* ptem = pq->phead->next;
free(pq->phead);
pq->phead = ptem;
}
}
取队头就很简单了,也是直接写
//取队头
QueueDataType QueueFront(Queue* pq)
{
//检查队列是否为空
assert(!QueueEmpty(pq));
return pq->phead->data;
}
取队尾更是无需多言
//取队尾的数据
void QueueBack(Queue* pq)
{
assert(!QueueEmpty(pq));
return pq->ptail->data;
}
(三)销毁队列
最后的环节也必然是我们的销毁队列
//销毁队列
void QueueDestroy(Queue* pq)
{
assert(pq);
//新定义一个结点用来遍历队列
QueueNode* pcur = pq->phead;
//开始遍历链表销毁
while (pcur)
{
//再新定义一个结点来保存下一个节点
QueueNode* ptem = pcur->next;
free(pcur);
pcur = ptem;
}
pq->phead = pq->ptail = NULL;
}