当前位置: 首页 > 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;这使得程序更加灵活和具有扩展性。动态编程则使得程序能够根据运行…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录&#xff0c;不允许匿名访问&#xff0c;kefu只能访问/data/kefu目录&#xff0c;不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

Java毕业设计:WML信息查询与后端信息发布系统开发

JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发&#xff0c;实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构&#xff0c;服务器端使用Java Servlet处理请求&#xff0c;数据库采用MySQL存储信息&#xff0…...