当前位置: 首页 > news >正文

第 3 章 栈和队列(单链队列)

1. 背景说明

队列(queue)是一种先进先出(first in first out,缩为 FIFO)的线性表。它只允许在表的一端进行插入,而在另一端删除元素。

2. 示例代码

1)status.h

/* DataStructure 预定义常量和类型头文件 */#ifndef STATUS_H
#define STATUS_H/* 函数结果状态码 */
#define TRUE 					1			/* 返回值为真 */
#define FALSE 					0			/* 返回值为假 */
#define RET_OK 					0			/* 返回值正确 */
#define INFEASIABLE    		   	2			/* 返回值未知 */
#define ERR_MEMORY     		   	3			/* 访问内存错 */
#define ERR_NULL_PTR   			4			/* 空指针错误 */
#define ERR_MEMORY_ALLOCATE		5			/* 内存分配错 */
#define ERR_NULL_STACK			6			/* 栈元素为空 */
#define ERR_PARA				7			/* 函数参数错 */
#define ERR_OPEN_FILE			8			/* 打开文件错 */
#define ERR_NULL_QUEUE			9			/* 队列为空错 */
typedef int Status;							/* Status 是函数的类型,其值是函数结果状态代码,如 OK 等 */
typedef int Bollean;						/* Boolean 是布尔类型,其值是 TRUE 或 FALSE */#endif // !STATUS_H

2) linkQueue.h

/* 单链队列 —— 队列的链式存储结构头文件 */#ifndef LINKQUEUE_H
#define LINKQUEUE_H#include "status.h"typedef int QElemType;typedef struct QNode {QElemType data;struct QNode *next;
} QNode, *QueuePtr;typedef struct {QueuePtr front, rear;
} LinkQueue;/* 构造一个空队列 Q */
Status InitQueue(LinkQueue *Q);/* 销毁队列 Q(无论空否均可) */
Status DestroyQueue(LinkQueue *Q);/* 将 Q 清为空队列 */
Status ClearQueue(LinkQueue *Q);/* 若 Q 为空队列,则返回 TRUE,否则返回 FALSE */
Bollean QueueEmpty(const LinkQueue *Q);/* 求队列的长度 */
int QueueLength(LinkQueue *Q);/* 若队列不空,则用 e 返回 Q 的队头元素,并返回 OK, 否则返回 ERROR */
Status GetQueueHead(const LinkQueue *Q, QElemType *e);/* 插入元素 e 为 Q 的新的队尾元素 */
Status EnQueue(LinkQueue *Q, QElemType e);/* 若队列不空,删除 Q 的队头元素,用 e 返回其值,并返回 OK, 否则返回 ERROR */
Status DeQueue(LinkQueue *Q, QElemType *e);/* 从队头到队尾依次对队列 Q 中每个元素调用函数 vi() */
Status QueueTraverse(const LinkQueue *Q, void(*vi)(QElemType));#endif // !LINKQUEUE_H

3) linkQueue.c

/* 单链队列 —— 队列的链式存储结构源文件 */#include "linkQueue.h"
#include <stdio.h>
#include <stdlib.h>/* 构造一个空队列 Q */
Status InitQueue(LinkQueue *Q)
{Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode));if (!Q->front) {printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_MEMORY_ALLOCATE);return ERR_MEMORY_ALLOCATE;}Q->front->next = NULL;return RET_OK;
}/* 销毁队列 Q(无论空否均可) */
Status DestroyQueue(LinkQueue *Q)
{while (Q->front) {Q->rear = Q->front->next;free(Q->front);Q->front = Q->rear;}return RET_OK;
}/* 将 Q 清为空队列 */
Status ClearQueue(LinkQueue *Q)
{Q->rear = Q->front;QueuePtr p = Q->front->next;Q->front->next = NULL;QueuePtr q = NULL;while (p) {q = p;p = p->next;free(q);}return RET_OK;
}/* 若 Q 为空队列,则返回 TRUE,否则返回 FALSE */
Bollean QueueEmpty(const LinkQueue *Q)
{return (Q->front == Q->rear) ? TRUE : FALSE;
}/* 求队列的长度 */
int QueueLength(LinkQueue *Q)
{int length = 0;QueuePtr p = Q->front;while (p != Q->rear) {++length;p = p->next;}return length;
}/* 若队列不空,则用 e 返回 Q 的队头元素(队头元素为 front 的下一个元素), 并返回 OK, 否则返回 ERROR */
Status GetQueueHead(const LinkQueue *Q, QElemType *e)
{if (Q->front == Q->rear) {printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_NULL_QUEUE);return ERR_NULL_QUEUE;}*e = Q->front->next->data;return RET_OK;
}static QueuePtr MakeNewQueueNode(QElemType e)
{QueuePtr p = (QueuePtr)malloc(sizeof(QNode));if (!p) {printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_MEMORY_ALLOCATE);return NULL;}p->data = e;p->next = NULL;return p;
}/* 插入元素 e 为 Q 的新的队尾元素 */
Status EnQueue(LinkQueue *Q, QElemType e)
{QueuePtr p = MakeNewQueueNode(e);if (p == NULL) {printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_NULL_PTR);return ERR_NULL_PTR;}Q->rear->next = p;Q->rear = p;return RET_OK;
}/* 若队列不空,删除 Q 的队头元素,用 e 返回其值,并返回 OK, 否则返回 ERROR */
Status DeQueue(LinkQueue *Q, QElemType *e)
{if (Q->front == Q->rear) {printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_NULL_QUEUE);return ERR_NULL_QUEUE;}QueuePtr p = Q->front->next;*e = p->data;Q->front->next = p->next;if (Q->rear == p) {Q->rear = Q->front;}free(p);return RET_OK;
}/* 从队头到队尾依次对队列 Q 中每个元素调用函数 vi() */
Status QueueTraverse(const LinkQueue *Q, void(*vi)(QElemType))
{QueuePtr p = Q->front->next;while (p) {vi(p->data);p = p->next;}return RET_OK;
}

4) auxiliary.h

/* 辅助函数头文件 */#ifndef AUXILIARY_H
#define AUXILIARY_H#include "linkQueue.h"/* 打印栈元素 */
void Print(QElemType e);#endif // !AUXILIARY_H

5) auxiliary.c

/* 辅助函数实现源文件 */#include "auxiliary.h"
#include <stdio.h>/* 打印栈元素 */
void Print(QElemType e)
{printf("%d ", e);
}

6) main.c

/* 入口程序源文件 */#include "status.h"
#include "auxiliary.h"
#include "linkQueue.h"
#include <stdio.h>int main(void)
{LinkQueue Q;Status ret = InitQueue(&Q);if (ret == RET_OK) {printf("Initialize queue success!\n");}printf("The queue is %s\n", (QueueEmpty(&Q) == TRUE) ? "empty" : "not empty");printf("The length of the queue is %d\n", QueueLength(&Q));EnQueue(&Q, -5);EnQueue(&Q, 5);EnQueue(&Q, 10);printf("After insert 3 elements, the length of the queue is %d\n", QueueLength(&Q));printf("The queue is %s\n", (QueueEmpty(&Q) == TRUE) ? "empty" : "not empty");printf("The elements of the queue is: ");QueueTraverse(&Q, Print);printf("\n");QElemType e;ret = GetQueueHead(&Q, &e);if (ret == RET_OK) {printf("The element of the head of the queue is %d\n", e);}DeQueue(&Q, &e);printf("Delete the element of the head of the queue %d\n", e);ret = GetQueueHead(&Q, &e);if (ret == RET_OK) {printf("The new element of the head of the queue is %d\n", e);}ClearQueue(&Q);printf("After clear the queue, Q.front = %p, Q.rear = %p, Q.front->next = %p\n",Q.front, Q.rear, Q.front->next);DestroyQueue(&Q);printf("After destroy the queue, Q.front = %p, Q.rear = %p\n", Q.front, Q.rear);return 0;
}

3. 输出示例

注意:free() 函数的作用并不仅仅把内存释放,还将指针置为空。

相关文章:

第 3 章 栈和队列(单链队列)

1. 背景说明 队列(queue)是一种先进先出(first in first out,缩为 FIFO)的线性表。它只允许在表的一端进行插入&#xff0c;而在另一端删除元素。 2. 示例代码 1&#xff09;status.h /* DataStructure 预定义常量和类型头文件 */#ifndef STATUS_H #define STATUS_H/* 函数结果…...

【DFS】1254. 统计封闭岛屿的数目

1254. 统计封闭岛屿的数目 解题思路 封闭岛屿就是上下左右全部被1包围的0 也就是靠边的0不算做封闭岛屿首先将上下左右的边界上的岛屿全部变成海洋然后在对剩下的岛屿进行DFS遍历 class Solution {public int closedIsland(int[][] grid) {// 封闭岛屿就是上下左右全部被1包…...

C#--sugarClient使用之ColumnName

使用Sugar ORM框架可以很方便地实现表名和实体名的映射&#xff0c;可以按照以下步骤进行操作&#xff1a; 创建一个实体类&#xff0c;定义实体的属性及其他信息。 [SugarTable("user_info")] // 指定实体对应的表名 public class User {public int Id { get; set…...

深度学习-4-二维目标检测-YOLOv5源码测试与训练

本文采用的YOLOv5源码是ultralytics发行版3.1 YOLOv5源码测试与训练 1.Anaconda环境配置 1.1安装Anaconda Anaconda 是一个用于科学计算的 Python 发行版&#xff0c;支持 Linux, Mac, Windows, 包含了众多流行的科学计算、数据分析的 Python 包。 官方网址下载安装包&…...

找不到msvcp140.dll的解决方法【msvcp140.dll修复工具下载】

今天&#xff0c;我将为大家分享一个与我们日常工作息息相关的话题——msvcp140.dll重新安装的5种解决方法。在接下来的时间里&#xff0c;我将向大家介绍什么是msvcp140.dll,为什么会丢失&#xff0c;以及它的用途。最后&#xff0c;我将为大家提供5种解决方法&#xff0c;帮助…...

内网隧道代理技术(二十)之 CS使用HTTP代理上线不出网机器

CS使用HTTP代理上线不出网机器 CS工具自带上线不出网机器 如图A区域存在一台中转机器,这台机器可以出网,这种是最常见的情况。我们在渗透测试的过程中经常是拿下一台边缘机器,其有多块网卡,边缘机器可以访问内网机器,内网机器都不出网。这种情况下拿这个边缘机器做中转,…...

安卓 tcp 客户端

安卓 tcp 客户端 Server:8888 是Qt 写的Tcp 服务器 ip 是 192.168.2.103 port是8888 安卓手机运行 kotlin 语法的Tcp Client &#xff0c;连接&#xff0c;收发数据 效果如下图 Tcpclient package com.example.myapplicationimport android.os.Handler import android.os.Loo…...

flutter plugins插件【三】【Flutter Intl】

3、 Flutter Intl 多语言国际化 在Android Studio中菜单Tools找到flutter intl创建多语言配置。 创建后会在pubspec.yaml出现 flutter_intl:enabled: true 在工程的lib会生成l10n与generated文件夹 l10n包含 intl_en.arb intl_zn.arb 我们在intl_en.arb添加 { home: &quo…...

简单了解ICMP协议

目录 一、什么是ICMP协议&#xff1f; 二、ICMP如何工作&#xff1f; 三、ICMP报文格式 四、ICMP的作用 五、ICMP的典型应用 5.1 Ping程序 5.2 Tracert(Traceroute)路径追踪程序 一、什么是ICMP协议&#xff1f; ICMP因特网控制报文协议是一个差错报告机制&#xff0c;…...

MVCC究竟是什么?

&#xff11;.MVCC概念 MVCC&#xff0c;全称多版本并发控制 MVCC究竟是什么&#xff1f; 通俗的来说MVCC就是为了在读取数据时不加锁来提高读取效率的一种办法&#xff0c;MVCC解决的是读写时线程安全问题&#xff0c;线程不用去抢占读写锁。MVCC中的读就是快照读&#xff0c…...

Kafka知识点总结

常见名词 生产者和消费者 同一个消费组下的消费者订阅同一个topic时&#xff0c;只能有一个消费者收到消息 要想让订阅同一个topic的消费者都能收到信息&#xff0c;需将它们放到不同的组中 分区机制 启动方法 生成者和消费者监听客户端...

K8s最基本概念

1.K8s概述和特性 k8s是谷歌在2014年开业的容器化集群管理系统 使用K8s进行容器化应用部署 使用K8s利用应用扩展 k8s目标实施让部署容器化应用更加简洁高效-------集群管理系统 1.1 K8s特性 1) 自动装箱&#xff1a;基于容器对应用运行环境的资源配置 2&#xff09;自…...

vulnhub渗透测试靶场练习2

靶场介绍 靶场名&#xff1a;easy_cloudantivirus 靶场地址&#xff1a;https://www.vulnhub.com/entry/boredhackerblog-cloud-av,453 环境搭建 依旧使用VM VirtualBox搭建靶场&#xff0c;攻击机使用的是VMware中的kali&#xff0c;需要将VMware虚拟机kali和virtualbox靶机…...

在R中安装TensorFlow、TensorFlow_Probability、numpy(R与Python系列第二篇)

目录 前言&#xff1a; 1-安装tensorflow库 Step1: 下载R包tensorflow Step2&#xff1a;安装TensorFlow库 Step3&#xff1a;导入R中 2-安装tensorflow_probability库 Step1&#xff1a;下载R包&#xff1a;tfprobability Step2&#xff1a;安装TensorFlow Probability …...

十大管理——项目成本管理

目录 1.成本管理概念 2.成本管理的四个过程域 2.1四个过程的整体理解 ​2.2四个过程的ITO口诀版记忆 2.3过程1——制定项目管理计划 ​2.4过程2——项目成本估算​ 2.5过程3——项目成本预算 2.5过程4——项目成本控制 3计算题 1.成本管理概念 项目成本管理就是要确保…...

Java BIO、NIO、AIO学习总结

前言&#xff1a;关于BIO/NIO/AIO的文章已经汗牛充栋&#xff0c;俺最近比较闲试图系统学习一下&#xff0c;希望大侠多多指教&#xff01; 先来个例子理解一下概念&#xff0c;以银行取款为例&#xff1a; 同步 &#xff1a; 自己亲自出马持银行卡到银行取钱&#xff08;使用…...

sql各种注入案例

目录 1.报错注入七大常用函数 1)ST_LatFromGeoHash (mysql>5.7.x) 2)ST_LongFromGeoHash &#xff08;mysql>5.7.x&#xff09; 3)GTID (MySQL > 5.6.X - 显错<200) 3.1 GTID 3.2 函数详解 3.3 注入过程( payload ) 4)ST_Pointfromgeohash (mysql>5.…...

系统学习Linux-ELK日志收集系统

ELK日志收集系统集群实验 实验环境 角色主机名IP接口httpd192.168.31.50ens33node1192.168.31.51ens33noed2192.168.31.53ens33 环境配置 设置各个主机的ip地址为拓扑中的静态ip&#xff0c;并修改主机名 #httpd [rootlocalhost ~]# hostnamectl set-hostname httpd [root…...

IDEA2023隐藏.idea和.iml文件

IDEA2023隐藏.idea和.iml文件 1. 打开file -> setting,快捷键CtrlAlts2. Editor -> File types3. 点击右侧Ignore files and folders一栏4. 添加需要忽略的文件5. 最重要一步 IDEA新建项目会自动生成一个.idea文件夹和.iml文件&#xff0c;开发中不需要对这两个文件修改&…...

【深入浅出C#】章节 9: C#高级主题:反射和动态编程

反射和动态编程是C#和其他现代编程语言中重要的高级主题&#xff0c;它们具有以下重要性&#xff1a; 灵活性和扩展性&#xff1a;反射允许程序在运行时动态地获取和操作类型信息、成员和对象实例&#xff0c;这使得程序更加灵活和具有扩展性。动态编程则使得程序能够根据运行…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...