以链表为基础实现链式队列——————遍历、入队、出队 (基于C语言实现)
以链表为基础实现链式队列
如果打算以链表作为基础来实现队列的操作,可以避免内存浪费以及避免内存成片移动,只需要确定队头和队尾即可,一般把链表头部作为队头,可以实现头删,把链表尾部作为队尾,可以实现尾插。
需要注意的点:
- 遍历队列需要备份地址
- 出队需要考虑空列表、列表中只有一个数据的情况

下面是我的函数接口:
定义链式队列中的元素的数据类型
// 指的是链式队列中的元素的数据类型,用户可以根据需要进行修改
typedef int DataType_t;
创建链式队列的结构体类型
// 构造记录链式队列结点linkrqueuenode各项参数(指针域next+数据域data)
typedef struct LinkrQueueNode
{
DataType_t data; // 数据域
struct LinkrQueueNode *next; // 指针域
} LinkrQueueNode_t
创建管理链式队列的结构体类型(队首+队尾)
// 构造记录链式队列linkrqueue各项参数(队列的队头+队尾)的结构体
typedef struct LinkrQueue
{
LinkrQueueNode_t *Rear; // 队首,记录头结点地址
LinkrQueueNode_t *Front; // 队尾,记录尾结点地址
} LinkrQueue_t;
创建一个链式队列,并对其初始化
/******************************************************
*
* name : Linkqueue_Create
* function : 创建一个链式队列,并对其初始化
* argument :None
* retval : 链式队列记录者的地址
* author : Dazz
* date : 2024/4/26
* note : None
*
* *******************************************************/
LinkrQueue_t *LinkQueue_Create(void)
{
// 创建记录链式队列的结构体,并对其初始化
LinkrQueue_t *record = (LinkrQueue_t *)calloc(1, sizeof(LinkrQueue_t));
// 判断链式队列的记录者是否申请成功
if (NULL == record)
{
printf("The link queue application failed!\n");
exit(-1); // 程序异常终止
}
// 对链式队列的记录者进行初始化
record->Front = NULL;
record->Rear = NULL;
return record;
}
判断链式队列是否为空
/******************************************************
*
* name : Linkqueue_Create
* function : 判断链式队列是否为空
* argument :None
* retval : 队链为空返回1,否则返回0
* author : Dazz
* date : 2024/4/26
* note : None
*
* *******************************************************/
bool LinkQueue_IsEmpty(LinkrQueue_t *record)
{
return ((record->Front == NULL) && (record->Rear == NULL)) ? true : false;
}
创建一个新的结点,并对该结点进行初始化(数据域 + 指针域)
/******************************************************
*
* name : LinkQueueNode_Create
* function : 创建一个新的结点,并对该结点进行初始化(数据域 + 指针域)
* argument
* @data :需要传入结点中的数据
*
* retval : 新结点的地址
* author : Dazz
* date : 2024/4/26
* note : None
*
* *******************************************************/
LinkrQueueNode_t *LinkQueueNode_Create(DataType_t data)
{
// 创建新的结点
LinkrQueueNode_t *New = (LinkrQueueNode_t *)calloc(1, sizeof(LinkrQueueNode_t));
// 判断是否创建成功
if (NULL == New)
{
printf("The new node creation failed\n");
return;
}
// 对新结点初始化
New->next = NULL;
New->data = data;
return New;
}
将结点入队
/******************************************************
*
* name : Linkqueue_Enqueue
* function : 将结点入队
* argument
* @record :链式队列记录者的地址
* @data :结点数据域里的数据
*
* retval : 成功返回1,否则为0
* author : Dazz
* date : 2024/4/26
* note : None
*
* *******************************************************/
bool Linkqueue_Enqueue(LinkrQueue_t *record, DataType_t data)
{
// 创建新结点
LinkrQueueNode_t *New = LinkQueueNode_Create(data);
// 判断新结点是否创建成功
if (NULL == New)
return false;
if (LinkQueue_IsEmpty(record)) // 链队为空的情况
{
record->Front = New; // 链队记录者的Front指向新结点
record->Rear = New; // 链队记录者的Rear指向新结点
}
else // 链队不为空的情况
{
record->Rear->next = New; // 将尾结点的指针域指向新结点
record->Rear = New; // 将管理者的Rear指向新结点
}
return true;
}
遍历链队,打印每个结点中的数据
/******************************************************
*
* name : PrintfAllNodes
* function : 遍历链队,打印每个结点中的数据
* argument
* @record :记录者的地址
*
* retval : None
* author : Dazz
* date : 2024/4/24
* note : None
*
* *******************************************************/
void PrintfAllNodes(LinkrQueue_t *record)
{
// 判断队列是否为空,如为空,直接退出
if (LinkQueue_IsEmpty(record))
{
printf("The queue is empty\n");
return;
}
// 对记录者的rear进行备份
LinkrQueueNode_t *temp = record->Front;
// 用循环遍历链队
while (temp->next != NULL)
{
printf("%d\n", temp->data);
temp = temp->next;
}
printf("%d\n", temp->data);
}
将链队出队
/******************************************************
*
* name : LinkQueue_Dequeue
* function : 将链队出队
* argument
* @record :记录者的地址
*
* retval : 出队的数据
* author : Dazz
* date : 2024/4/24
* note : None
*
* *******************************************************/
DataType_t LinkQueue_Dequeue(LinkrQueue_t *record)
{
// 定义变量记录要出队的数据
DataType_t temp = 0;
// 判断链队是否为空
if (LinkQueue_IsEmpty(record))
{
printf("The queue is empty and cannot be dequeued\n");
return;
}
// 队列只有一个结点的情况
else if (NULL == record->Front->next)
{
temp = record->Front->data; // 对要出队的数据进行备份
LinkrQueueNode_t *temp = record->Front; // 对要出队的地址进行备份
record->Front = NULL; // 重新把记录器的Front指向NULL
record->Rear = NULL; // 重新把记录器的Rear指向NULL
free(temp); // 释放要出队的结点
}
else
{
// 队列不为空的情况,数据需从队首出队
temp = record->Front->data; // 对要出队的数据进行备份
LinkrQueueNode_t *nodetemp = record->Front; // 对要出队的地址进行备份
record->Front = nodetemp->next; // 将记录者的Front指向出队结点的后面的结点
nodetemp->next = NULL; // 将要出对的结点的指针域指向NULL
free(nodetemp); // 释放要出队的结点
}
return temp;
}

浙公网安备 33010602011771号