C语言实现队列数据结构:思路与代码详解

embedded/2025/3/14 15:13:01/

目录

一、引言 

二、整体思路 

三、代码模块分析 

(一)头文件包含与宏定义 

(二)数据类型定义 

(三)队列操作函数 

1. 队列初始化 

2. 队列销毁 

3. 入队操作 

4. 出队操作 

5. 获取队头元素 

6. 获取队尾元素 

7. 获取队列大小 

8. 判断队列是否为空 

(四)主函数测试 

四、总结 


作者主页:共享家9527-CSDN博客

一、引言
 


队列是一种重要的数据结构,遵循先进先出(FIFO)的原则。在C语言中,我们可以通过自定义结构体和一系列操作函数来实现一个队列。本文将详细介绍如何实现一个简单的队列,并对代码的各个部分进行深入分析。
 


二、整体思路
 


队列的实现主要涉及队列节点的定义、队列结构体的定义以及对队列的各种操作,如初始化、入队、出队、获取队头和队尾元素、判断队列是否为空和获取队列大小等。我们将这些操作模块化,每个函数负责一个特定的功能,使得代码结构清晰,易于维护和扩展。
 


三、代码模块分析
 


(一)头文件包含与宏定义
 


c#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>


 
 _CRT_SECURE_NO_WARNINGS 宏定义用于关闭Visual Studio中一些函数的安全警告。后面依次包含了标准输入输出库、标准库、布尔类型库和断言库,为后续代码提供必要的功能支持。
 


(二)数据类型定义
 


ctypedef int QDatatype;
typedef struct QueueNode
{struct QueueNode* next;QDatatype data;
}QNode;typedef struct Queue
{QNode* head;QNode* tail;int size;
}Queue;


 
-  QDatatype  定义为  int  类型,表示队列中存储的数据类型,这里是整型,也可以根据实际需求改为其他类型。
 
-  QueueNode  结构体定义了队列节点,包含一个指向下一个节点的指针  next  和存储数据的  data  成员。
 
-  Queue  结构体表示整个队列,包含指向队头的指针  head 、指向队尾的指针  tail  和记录队列元素个数的  size 。
 


(三)队列操作函数
 


1. 队列初始化
 


cvoid QueueInit(Queue* pq)
{pq->head = pq->tail = NULL;pq->size = 0;
}


 
 QueueInit  函数用于初始化一个队列,将队头和队尾指针设为  NULL ,队列大小设为  0 。
 


2. 队列销毁
 


cvoid QueueDestroy(Queue* pq)
{assert(pq);Queue* cur = pq->head;while (cur){pq->head = pq->head->next;free(cur);cur = pq->head;}pq->head = pq->tail = NULL;pq->size = 0;
}


 
 QueueDestroy  函数用于释放队列占用的内存空间。通过遍历队列,逐个释放每个节点,最后将队头、队尾指针设为  NULL ,队列大小设为  0 。
 


3. 入队操作
 


cvoid QueuePush(Queue* pq, QDatatype x)
{QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");return;}newnode->data = x;newnode->next = NULL;if (pq->head == NULL){pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}pq->size++;
}


 
 QueuePush  函数用于将一个元素入队。首先分配一个新节点的内存空间,若分配失败则打印错误信息并返回。然后将新节点的数据设为传入的元素值, next  指针设为  NULL 。如果队列为空,则新节点既是队头也是队尾;否则将新节点连接到队尾,并更新队尾指针。最后队列大小加  1 。
 


4. 出队操作
 


cvoid QueuePop(Queue* pq)
{assert(pq);assert(pq->head != NULL);if (pq->head->next == NULL){free(pq->head);pq->head = pq->tail = NULL;}else{QNode* next = pq->head->next;free(pq->head);pq->head = next;}pq->size--;
}


 
 QueuePop  函数用于将队头元素出队。首先进行断言,确保队列指针有效且队列不为空如果队列只有一个元素,释放队头节点并将队头、队尾指针设为  NULL ;否则保存队头节点的下一个节点,释放队头节点,然后将队头指针指向下一个节点。最后队列大小减  1 。
 


5. 获取队头元素
 


cQDatatype QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->head->data;
}


 
 
 QueueFront  函数用于获取队头元素的值。先进行断言确保队列有效且不为空,然后返回队头节点的数据。
 


6. 获取队尾元素
 


cQDatatype QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->tail->data;
}


 
 QueueBack  函数用于获取队尾元素的值。同样先进行断言确保队列有效且不为空,然后返回队尾节点的数据。
 


7. 获取队列大小
 


cint QueueSize(Queue* pq)
{return pq->size;
}QueueSize  函数直接返回队列结构体中记录的元素个数。


8. 判断队列是否为空
 


cbool QueueEmpty(Queue* pq)
{assert(pq);return pq->head == NULL;
}


 
 QueueEmpty  函数通过判断队头指针是否为  NULL  来确定队列是否为空,为空则返回  true ,否则返回  false 。
 


(四)主函数测试
 


cint main()
{Queue Q;QueueInit(&Q);QueuePush(&Q, 1);QueuePush(&Q, 2);QueuePush(&Q, 3);QueuePush(&Q, 4);QueuePush(&Q, 5);while (!QueueEmpty(&Q)){printf("%d ", QueueFront(&Q));QueuePop(&Q);}printf("\n");QueueDestroy(&Q);return 0;
}


 
在  main  函数中,我们对实现的队列进行了测试。首先初始化一个队列,然后依次将  1  到  5  这五个元素入队,接着通过循环不断获取队头元素并打印,同时将其出队,直到队列为空。最后销毁队列,释放内存。
 


四、总结
 


通过以上模块化的代码实现,我们完成了一个基本的队列数据结构。每个函数都有明确的功能,使得代码逻辑清晰,易于理解和维护。在实际应用中,可以根据具体需求对队列进行进一步的扩展和优化,如添加更多的操作函数或者改变数据存储类型等。


http://www.ppmy.cn/embedded/172517.html

相关文章

stm32 蓝桥杯 物联网 独立键盘的使用

在蓝桥杯物联网平台里面&#xff0c;有5个外接设备&#xff0c;其中有一个就是6个独立按键。首先&#xff0c;我们先看一下按键有关的电路图。 电路图与cubemx设定 由图可见&#xff0c;独立键盘组由两行三列构成&#xff0c;我们通过行列来锁定要访问的独立按键在哪。ROW1挂…

垃圾收集算法与收集器

在 JVM 中&#xff0c;垃圾收集&#xff08;Garbage Collection, GC&#xff09;算法的核心目标是自动回收无用对象的内存&#xff0c;同时尽量减少对应用性能的影响。以下是 JVM 中主要垃圾收集算法的原理、流程及实际应用场景的详细介绍&#xff1a; 一、标记-清除算法&#…

深入理解pytest框架中的conftest.py:使用与作用原理

pytest是Python中最流行的测试框架之一&#xff0c;以其简洁、灵活和强大的功能而闻名。在pytest中&#xff0c;conftest.py文件是一个特殊的文件&#xff0c;用于共享测试配置、夹具&#xff08;fixtures&#xff09;和插件。理解conftest.py的使用和作用原理&#xff0c;可以…

leetcode283.移动零

题目&#xff1a; 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1,0,3,12] 输出:[1,3,12,0,0] 示例 2: 输入: nums…

碰一碰发视频源码搭建,碰一碰发视频私有化部署,碰一碰发视频OEM贴牌

引言 随着移动互联网的快速发展&#xff0c;短视频应用成为了用户日常娱乐和信息获取的重要方式。碰一碰发视频功能作为一种新颖的交互方式&#xff0c;能够通过设备之间的简单触碰实现视频的快速分享。本文将详细介绍如何搭建碰一碰发视频的源码&#xff0c;并进行私有化部署…

解决Docker Desktop中ext4.vhdx文件过大的问题

ext4.vhdx是Docker Desktop在Windows系统上使用WSL2&#xff08;Windows Subsystem for Linux 2&#xff09;时&#xff0c;用于存储Linux文件系统的虚拟硬盘文件。 基本概念 VHDX格式&#xff1a;VHDX是微软推出的一种虚拟硬盘格式&#xff0c;具有更大的存储容量、更好的性能…

SQL Server查询优化

最常用&#xff0c;最有效的数据库优化方式 查询语句层面 避免全表扫描 使用索引&#xff1a;确保查询条件中的字段有索引。例如&#xff0c;查询语句 SELECT * FROM users WHERE age > 20&#xff0c;若 age 字段有索引&#xff0c;数据库会利用索引快速定位符合条件的记…

基于Java 童装在线销售系统(源码+lw+部署文档+讲解),源码可白嫖!

摘要&#xff1a; 当今社会进入了科技进步、经济社会快速发展的新时代。国际信息和学术交流也不断加强&#xff0c;计算机技术对经济社会发展和人民生活改善的影响也日益突出&#xff0c;人类的生存和思考方式也产生了变化。传统购物管理采取了人工的管理方法&#xff0c;但这…