链式队列的基本概念
链式队列是一种常见的数据结构,它使用链表作为其底层数据存储结构。链式队列的特点是动态的内存分配,可以有效地处理队列的入队和出队操作。下面,我将介绍链式队列的实现方法,并提供相应的C语言代码示例。
链式队列遵循先进先出(FIFO)原则,即最早进入队列的元素将最先被移除。它由节点组成,每个节点包含数据和指向下一个节点的指针。
实现链式队列的步骤
- 创建队列:首先,我们需要创建一个队列结构,它包含当前队列的大小、队首指针和队尾指针。
- 创建节点:每个节点包含数据和指向下一个节点的指针。
- 判断队列是否为空:检查队列的当前大小是否为0。
- 入队操作:在队尾添加新节点。
- 出队操作:从队首移除节点。
- 获取队首元素:返回队首节点的数据,但不移除节点。
- 获取队列大小:返回队列中元素的数量。
- 销毁队列:释放队列占用的所有内存。
链式队列的操作说明参考书籍《大话数据结构》:
项目文件:LinkQueue.h,其中有结构体以及相关的函数声明
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
// 定义队列中的元素类型
typedef int Datatype;
// 定义队列节点结构体
typedef struct QueueNode {
Datatype data; // 节点中的数据
struct QueueNode* next; // 指向下一个节点的指针
} QueueNode;
// 定义链式队列结构体
typedef struct LinkQueue {
QueueNode* front; // 队列头部节点指针
QueueNode* rear; // 队列尾部节点指针
int curSize; // 队列中元素的数量
} LinkQueue;
// 初始化链式队列
LinkQueue* createLinkQueue();
//创建节点
QueueNode* createNode(Datatype data);
//判断链式队列是否为空
bool isEmptyLinkQueue(LinkQueue* queue);
//入队操作
void enLinkQueue(LinkQueue* queue, Datatype element);
//出队操作
void deLinkQueue(LinkQueue* queue);
// 获取队列的前端元素
Datatype peekLinkQueue(LinkQueue* queue);
// 获取链式队列的大小
int sizeLinkQueue(LinkQueue* queue);
// 销毁链式队列
void destroyLinkQueue(LinkQueue* queue);
LinkQueue.c:其中是全部的函数实现,需要在其中引用LinkQueue.h
#include "LinkQueue.h"
//创建链式队列
LinkQueue* createLinkQueue()
{
LinkQueue* queue = (LinkQueue*)malloc(sizeof(LinkQueue));
assert(queue);
queue->curSize = 0;
queue->front = queue->rear = NULL;
return queue;
}
//创建节点
QueueNode* createNode(Datatype data)
{
QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
assert(newNode);
newNode->data = data;
newNode->next = NULL;
return newNode;
}
//判断链式队列是否为空
bool isEmptyLinkQueue(LinkQueue* queue)
{
assert(queue);
if (queue->curSize == 0)
{
return true;
}
else
{
return false;
}
}
//入队操作 这里思考链表的表尾和队列的表尾是否是一样的
//这里一定要思考插入的位置在哪?队列的尾是链表的尾,所以入队相当于链表数据尾插
void enLinkQueue(LinkQueue* queue, Datatype data)
{
assert(queue);
//创建新的节点
QueueNode* newNode = createNode(data);
//如果链表为空,那么表头和表尾指针指向同一个节点
if (queue->curSize == 0)
{
queue->front = newNode;
queue->rear = newNode;
}
else
{
//先插入数据,而后更新队列尾指针
queue->rear->next = newNode;
queue->rear = newNode;
}
queue->curSize++;
}
//出队操作 (数据头删)
void deLinkQueue(LinkQueue* queue)
{
assert(queue);
//如果队列为空,那么无需删除直接返回
if (queue->curSize==0)
{
return;
}
//保存第一个节点
QueueNode* temp = queue->front;
//将表头指针移动到下一个节点
queue->front = queue->front->next;
//删除之前保存的第一个节点
free(temp);
queue->curSize--;
}
// 获取队列的前端元素
Datatype peekLinkQueue(LinkQueue* queue)
{
assert(queue);
assert(queue->curSize);
return queue->front->data;
}
// 获取链式队列的大小
int sizeLinkQueue(LinkQueue* queue)
{
assert(queue);
return queue->curSize;
}
// 销毁链式队列
void destroyLinkQueue(LinkQueue* queue)
{
assert(queue);
while (queue->curSize)
{
deLinkQueue(queue);
}
free(queue);
}
总结
链式队列是一种灵活且高效的数据结构,适用于需要动态内存分配的场景。通过上述代码,我们可以看到链式队列的实现相对简单,但功能强大。它在很多应用中都非常有用,比如任务调度、事件处理等。