队列
1. 队列概念和结构
队列与栈类似是一种特殊的线性表, 其只允许在一端删除数据, 在另外一端插入数据
删除数据的一端叫做队头, 插入数据的一端叫做队尾
删除与插入操作在队列中, 叫做出队和入队, 如下图

其次, 队列中的所有数据都遵守先进先出原则
比如要将1移出队列, 必须首先将数据0先出队列, 才能将数据1出队

2. 队列的实现
下图是实现队列的结构, 其中QueNode链表结构用来存储数据和记录数据之间的次序
Queue结构作为整体用来实现队列, head指向队头 (链表结构的第一个节点), tail指向队尾(最后一个节点), size记录队列中的数据个数

下面具体实现
队列结构及接口
typedef int QueDataType;
typedef struct QueNode
{
QueDataType data;
struct QueNode* next;
}QueNode;
typedef struct Queue
{
QueNode* head;
QueNode* tail;
int size;
}Queue;
// 初始化队列
void QueInit(Queue* pq);
// 销毁队列
void QueDestroy(Queue* pq);
// 入队
void QuePush(Queue* pq, QueDataType x);
// 出队
void QuePop(Queue* pq);
// 计算队列中数据个数
int QueSize(Queue* pq);
// 判空
bool isQueEmpty(Queue* pq);
// 取队头数据
QueDataType QueFront(Queue* pq);
// 取队尾数据
QueDataType QueBack(Queue* pq);
初始化队列
// 初始化队列
void QueInit(Queue* pq)
{
assert(pq);
pq->head = pq->tail = NULL;
pq->size = 0;
}

入队

// 入队
void QuePush(Queue* pq, QueDataType x)
{
assert(pq);
QueNode* newnode = (QueNode*)malloc(sizeof(QueNode));
if (NULL == newnode)
{
perror("QuePush::malloc fail");
return;
}
newnode->data = x;
newnode->next = NULL;
if (NULL == pq->head)
{
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
pq->size++;
}
出队


// 出队
void QuePop(Queue* pq)
{
assert(pq);
assert(pq->head);
if (NULL == pq->head->next)
{
free(pq->head);
pq->head = pq->tail = NULL;
}
else
{
QueNode* next = pq->head->next;
free(pq->head);
pq->head = next;
}
pq->size--;
}
计算队中数据个数
// 计算队列中数据个数
int QueSize(Queue* pq)
{
return pq->size;
}
判断队列是否为空
// 判空
bool isQueEmpty(Queue* pq)
{
return pq->size == 0;
}
取队头/尾数据
// 取队头数据
QueDataType QueFront(Queue* pq)
{
assert(pq);
assert(!isQueEmpty(pq));
return pq->head->data;
}
// 取队尾数据
QueDataType QueBack(Queue* pq)
{
assert(pq);
assert(!isQueEmpty(pq));
return pq->tail->data;
}
销毁队列
// 销毁队列
void QueDestroy(Queue* pq)
{
assert(pq);
QueNode* cur = pq->head;
while (cur)
{
QueNode* next = cur->next;
free(cur);
cur = next;
}
pq->head = pq->tail = NULL;
pq->size = 0;
}

完整代码
queue.h
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
typedef int QueDataType;
typedef struct QueNode
{
QueDataType data;
struct QueNode* next;
}QueNode;
typedef struct Queue
{
QueNode* head;
QueNode* tail;
int size;
}Queue;
// 初始化队列
void QueInit(Queue* pq);
// 销毁队列
void QueDestroy(Queue* pq);
// 入队
void QuePush(Queue* pq, QueDataType x);
// 出队
void QuePop(Queue* pq);
// 计算队列中数据个数
int QueSize(Queue* pq);
// 判空
bool isQueEmpty(Queue* pq);
// 取队头数据
QueDataType QueFront(Queue* pq);
// 取队尾数据
QueDataType QueBack(Queue* pq);
queue.c
#include "queue.h"
// 初始化队列
void QueInit(Queue* pq)
{
assert(pq);
pq->head = pq->tail = NULL;
pq->size = 0;
}
// 销毁队列
void QueDestroy(Queue* pq)
{
assert(pq);
QueNode* cur = pq->head;
while (cur)
{
QueNode* next = cur->next;
free(cur);
cur = next;
}
pq->head = pq->tail = NULL;
pq->size = 0;
}
// 入队
void QuePush(Queue* pq, QueDataType x)
{
assert(pq);
QueNode* newnode = (QueNode*)malloc(sizeof(QueNode));
if (NULL == newnode)
{
perror("QuePush::malloc fail");
return;
}
newnode->data = x;
newnode->next = NULL;
if (NULL == pq->head)
{
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
pq->size++;
}
// 出队
void QuePop(Queue* pq)
{
assert(pq);
assert(pq->head);
if (NULL == pq->head->next)
{
free(pq->head);
pq->head = pq->tail = NULL;
}
else
{
QueNode* next = pq->head->next;
free(pq->head);
pq->head = next;
}
pq->size--;
}
// 计算队列中数据个数
int QueSize(Queue* pq)
{
return pq->size;
}
// 判空
bool isQueEmpty(Queue* pq)
{
return pq->size == 0;
}
// 取队头数据
QueDataType QueFront(Queue* pq)
{
assert(pq);
assert(!isQueEmpty(pq));
return pq->head->data;
}
// 取队尾数据
QueDataType QueBack(Queue* pq)
{
assert(pq);
assert(!isQueEmpty(pq));
return pq->tail->data;
}
test.c
#include "queue.h"
int main()
{
Queue que;
QueInit(&que);
QuePush(&que, 1);
QuePush(&que, 2);
QuePush(&que, 3);
QuePush(&que, 4);
QuePush(&que, 5);
while (!isQueEmpty(&que))
{
printf("%d ", QueFront(&que));
QuePop(&que);
}
QueDestroy(&que);
}
浙公网安备 33010602011771号