目录
一. 队列的概念
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾出队列:进行删除操作的一端称为队头
二. 队列的实现
队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,需要频繁移动后面的元素,效率会比较低。
将要实现的接口以及定义的结构体:
//方便类型更改
typedef int QDataType;
//定义结点结构体
typedef struct QueueNode
{
QDataType val;
struct QueueNode* next;
}QNode;
//定义头尾指针结构体
typedef struct Queue
{
QNode* head;//存结点的头
QNode* tail;//存结点的尾
}Queue;
void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
void QueuePush(Queue* pq, QDataType x);
void QueuePop(Queue* pq);
bool QueueEmpty(Queue* pq);
size_t QueueSize(Queue* pq);
QDataType* QueueFront(Queue* pq);
QDataType* QueueBack(Queue* pq);
队列的初始化:
void QueueInit(Queue* pq)
{
assert(pq);//结构体必须存在
pq->head = pq->tail = NULL;
}
队列的销毁:
void QueueDestroy(Queue* pq)
{
assert(pq);//结构体必须存在
while (pq->head)
{
//存储下一个结点
QNode* next = pq->head->next;
//销毁结点
free(pq->head);
pq->head = next;
}
pq->head = NULL;
}
队列的入队:
以下是空队列和非空队列的入队操作图:
以下是代码的实现:
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
//创建结点
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
printf("malloc fail!\n");
exit(-1);
}
newnode->val = x;
newnode->next = NULL;
//当队列为空
if (pq->head == NULL && pq->tail == NULL)
{
pq->head = newnode;
pq->tail = newnode;
}
//队列不为空
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
}
队列的出队操作:
以下是操作图:
以下是代码:
void QueuePop(Queue* pq)
{
assert(pq);
assert(pq->head && pq->tail);//队列为空不能删除
//保存head后一个结点
QNode* next =pq->head->next;
//销毁结点
free(pq->head);
pq->head = NULL;
//结点大于一个
if (next)
{
pq->head = next;
}
//只有一个结点,tail也要置空,不然tail就是野指针了
else
{
pq->head = pq->tail = NULL;
}
}
判断队列是否为空:
bool QueueEmpty(Queue* pq)
{
assert(pq);
//为空的话,就返回true,否则false
return pq->head == NULL;
}
队列里的元素个数:
size_t QueueSize(Queue* pq)
{
assert(pq);
QNode* cur = pq->head;
size_t count = 0;
while (cur)
{
++count;
cur = cur->next;
}
return count;
}
返回队列的第一个元素:
QDataType* QueueFront(Queue* pq)
{
assert(pq);
//第一个元素为空的情况
if (pq->head == NULL)
{
return NULL;
}
return pq->head->val;
}
返回队列的最后一个元素:
QDataType* QueueBack(Queue* pq)
{
assert(pq);
//第一个元素为空的情况
if (pq->tail == NULL)
{
return NULL;
}
return pq->tail->val;
}