数据结构与算法学习笔记十---链队列的表示和实现(C语言)

目录

前言

1.什么是链队

2.链队的表示和实现

1.定义

2.初始化

3.销毁

4.清空

5.空队列

6.队列长度

7.获取队头

8.入队

9.出队

10.遍历队列

11.完整代码


前言

    本篇博客介绍链栈队列的表示和实现。

1.什么是链队

    链队是采用链式存储结构实现的队列。通常链队使用单链表表示。

   

图1.链队的示意图

     为了操作方便,我们给链队列增加一个头结点,令头指针始终指向头结点。

2.链队的表示和实现

1.定义

typedef int QElemType;
typedef int Status;
typedef struct QNode{QElemType data;struct QNode * next;
}QNode,*QueuePtr;
typedef struct {QueuePtr front;//队头指针QueuePtr rear;//队尾指针
}LinkQueue;

2.初始化

            初始化的时候给链队分配一个结点。

        图2.空队列

//初始化
Status initLinkQueue(LinkQueue * linkQueue){linkQueue->front =  linkQueue->rear = (QueuePtr)malloc(sizeof(QNode));if (!linkQueue->front) {return 0;}return 1;
}

3.销毁

        当需要销毁队列时,我们需要释放队列中所有节点的内存,并将队列结构体中的指针置空。

         我们需要遍历所有的结点,释放结点内存,最后置空头结点。

// 销毁队列
void destroyLinkQueue(LinkQueue *linkQueue) {while (linkQueue->front) { // 循环释放队列中所有节点的内存QueuePtr temp = linkQueue->front;linkQueue->front = linkQueue->front->next;free(temp);}linkQueue->rear = NULL; // 将 rear 指针置空
}

4.清空

        清空队列的方法与销毁队列的方法类似,但不释放队列结构体本身的内存,只释放队列中节点的内存并将队列恢复到初始状态。

// 清空队列
void clearLinkQueue(LinkQueue *linkQueue) {while (linkQueue->front) { // 循环释放队列中所有节点的内存QueuePtr temp = linkQueue->front;linkQueue->front = linkQueue->front->next;free(temp);}linkQueue->rear = NULL; // 将 rear 指针置空
}

5.空队列

        队头和队尾相同的时候为空队列。

// 判断队列是否为空
Status isLinkQueueEmpty(LinkQueue *linkQueue) {return linkQueue->front == NULL; // 如果队头指针为空,则队列为空
}

6.队列长度

// 计算队列长度
int getLinkQueueLength(LinkQueue *linkQueue) {int length = 0;QueuePtr p = linkQueue->front->next; // 从队头指针开始while (p != NULL) { // 遍历队列length++;p = p->next;}return length;
}

7.获取队头

        获取队头元素。

// 获取队列头结点
Status getLinkQueueFront(LinkQueue *linkQueue, QElemType *element) {if (linkQueue->front == NULL) { // 队列为空return 0;}*element = linkQueue->front->next->data; // 将队头节点的数据存储到 element 中return 1;
}

8.入队

        入队列的时候如下所示。

        图3.入队列示意图

// 入队列
Status enLinkQueue(LinkQueue * linkQueue,QElemType element){QueuePtr newNode = (QNode *)malloc(sizeof(QNode));//生成一个新节点if (!newNode) {return 0;}newNode->data = element;newNode->next = NULL;linkQueue->rear->next = newNode;linkQueue->rear = newNode;return 1;
}

9.出队

        出队列的时候如下如所示:

图4.出队列示意图

// 出队列
Status deLinkQueue(LinkQueue * linkQueue,QElemType *element){if (linkQueue->front == linkQueue->rear) {//空队列return 0;}QueuePtr p = linkQueue->front->next;// 指向头结点* element = p->data;linkQueue->front->next = p->next;//修改头指针if (linkQueue->front == p) {//如果仅有一个节点linkQueue->rear = linkQueue->front;//修改尾指针}free(p);return 1;
}

10.遍历队列

// 遍历队列(忽略头结点)
void traverseLinkQueueIgnoreHead(LinkQueue *linkQueue) {if (linkQueue->front == NULL || linkQueue->front->next == NULL) { // 队列为空或只有头结点printf("队列为空\n");return;}QueuePtr current = linkQueue->front->next; // 从头结点的下一个节点开始遍历while (current != NULL) { // 遍历直到队尾printf("%d\t", current->data); // 打印当前节点的数据current = current->next; // 移动到下一个节点}printf("\n");
}

11.完整代码

#include <stdlib.h>typedef int QElemType;
typedef int Status;
typedef struct QNode{QElemType data;struct QNode * next;
}QNode,*QueuePtr;
typedef struct {QueuePtr front;//队头指针QueuePtr rear;//队尾指针
}LinkQueue;//初始化
Status initLinkQueue(LinkQueue * linkQueue){linkQueue->front =  linkQueue->rear = (QueuePtr)malloc(sizeof(QNode));if (!linkQueue->front) {return 0;}return 1;
}
// 销毁队列
void destroyLinkQueue(LinkQueue *linkQueue) {while (linkQueue->front) { // 循环释放队列中所有节点的内存QueuePtr temp = linkQueue->front;linkQueue->front = linkQueue->front->next;free(temp);}linkQueue->rear = NULL; // 将 rear 指针置空
}
// 清空队列
void clearLinkQueue(LinkQueue *linkQueue) {while (linkQueue->front) { // 循环释放队列中所有节点的内存QueuePtr temp = linkQueue->front;linkQueue->front = linkQueue->front->next;free(temp);}linkQueue->rear = NULL; // 将 rear 指针置空
}
// 判断队列是否为空
Status isLinkQueueEmpty(LinkQueue *linkQueue) {return linkQueue->front == NULL; // 如果队头指针为空,则队列为空
}
// 计算队列长度
int getLinkQueueLength(LinkQueue *linkQueue) {int length = 0;QueuePtr p = linkQueue->front->next; // 从队头指针开始while (p != NULL) { // 遍历队列length++;p = p->next;}return length;
}
// 获取队列头结点
Status getLinkQueueFront(LinkQueue *linkQueue, QElemType *element) {if (linkQueue->front == NULL) { // 队列为空return 0;}*element = linkQueue->front->next->data; // 将队头节点的数据存储到 element 中return 1;
}
// 遍历队列
// 遍历队列(忽略头结点)
void traverseLinkQueueIgnoreHead(LinkQueue *linkQueue) {if (linkQueue->front == NULL || linkQueue->front->next == NULL) { // 队列为空或只有头结点printf("队列为空\n");return;}QueuePtr current = linkQueue->front->next; // 从头结点的下一个节点开始遍历while (current != NULL) { // 遍历直到队尾printf("%d\t", current->data); // 打印当前节点的数据current = current->next; // 移动到下一个节点}printf("\n");
}// 入队列
Status enLinkQueue(LinkQueue * linkQueue,QElemType element){QueuePtr newNode = (QNode *)malloc(sizeof(QNode));//生成一个新节点if (!newNode) {return 0;}newNode->data = element;newNode->next = NULL;linkQueue->rear->next = newNode;linkQueue->rear = newNode;return 1;
}
// 出队列
Status deLinkQueue(LinkQueue * linkQueue,QElemType *element){if (linkQueue->front == linkQueue->rear) {//空队列return 0;}QueuePtr p = linkQueue->front->next;// 指向头结点* element = p->data;linkQueue->front->next = p->next;//修改头指针if (linkQueue->front == p) {//如果仅有一个节点linkQueue->rear = linkQueue->front;//修改尾指针}free(p);return 1;
}void testLinkQueue(void){LinkQueue queue;if (initLinkQueue(&queue)) {printf("链队列初始化成功!\n");}else {printf("链队列初始化失败!\n");}if (isLinkQueueEmpty(&queue)) {printf("队列为空\n");}printf("队列长度:%d\n",getLinkQueueLength(&queue));for (int i = 1; i <= 10 ; i++) {if (enLinkQueue(&queue, i)) {printf("数据元素%d入队成功!\n",i);}else{printf("入队失败!\n");}}printf("遍历链队列初!\n");if (!isLinkQueueEmpty(&queue)) {printf("队列不为空\n");}QElemType headFront;if (getLinkQueueFront(&queue, &headFront)) {printf("队列头结点获取成功,队头元素为:%d\n",headFront);}traverseLinkQueueIgnoreHead(&queue);printf("队列长度:%d\n",getLinkQueueLength(&queue));printf("队列长度:%d\n",getLinkQueueLength(&queue));for (int i = 1; i <= 10 ; i++) {int element;if (deLinkQueue(&queue, &element)) {printf("出队列成功,出队列的数据元为素%d!\n",element);}else{printf("入队失败!\n");}}destroyLinkQueue(&queue);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/12356.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【知识拓展】大白话说清楚:IP地址、子网掩码、网关、DNS等

前言 工作中常听别人说的本地网络是什么意思&#xff1f;同一网段又是什么意思&#xff1f;它俩有关系吗&#xff1f; 在工作中内经常会遇到相关的网络问题&#xff0c;涉及网络通信中一些常见的词汇&#xff0c;如IP地址、子网掩码、网关和DNS等。具体一点&#xff1a;经常会…

申请免费的必应搜索API

申请免费的必应搜索API 文章目录 申请免费的必应搜索API前言一、原理1.1 登录1.2 进入1.3 获取密钥1.4 申请VISA信用卡1.5 创建必应自定义搜索资源 二、创建成功 前言 准备条件&#xff1a; 1、outlook邮箱 2、招商银行全币种VISA信用卡【建议之前就有一张招商银行信用卡&…

【opencv】图像拼接实验

实验环境&#xff1a;anaconda、jupyter notebook 实验用到的包&#xff1a;opencv、matplotlib、numpy 注&#xff1a;opencv在3.4.2之后sift就不是免费的了 我用的是3.4.1.15版本 实验使用到的图片 一、sift函数获取特征值 读入图片 book cv2.imread(book.png, cv2.IMRE…

【极简】如何估算大模型inference所需的内存量

1字节8bit 16float2字节 模型后面的xxb的单位是字节。 1b 字节≈ 0.93G&#xff0c;这个是以8bit运行&#xff0c;4bit减半&#xff0c;16bit&#xff08;float&#xff09;加倍&#xff0c;32bit&#xff08;double&#xff09;炒鸡加倍。 剩下的是小头&#xff0c;需要参数计…

苹果macOS无法给App麦克风授权解决办法

好久没有在电脑上录制课程了&#xff0c;有些东西还是录下来记忆深刻&#xff0c;却意外发现MAC系统升级后无法授权给第三方的App使用摄像头和麦克风&#xff0c;而录屏软件是需要开启麦克风和摄像头才能录制屏幕上的操作和声音&#xff0c;官方提示在第三方APP若有使用摄像头和…

css的4种导入方式

熟悉CSS样式4种的引用方式&#xff0c;分别为行内式、内嵌式、链入式和导入式。 行内式 <标签名 style"属性1:属性值1;属性2:属性值2;属性3:属性值3;">内容</ 标签名>style是标签的属性&#xff0c;实际上任何HTML标签都拥有style属性&#xff0c;用来…

pyqt QComboBox下拉列表框控件

pyqt QComboBox下拉列表框控件 QComboBox效果代码 QComboBox QComboBox 是 PyQt&#xff08;中的一个控件&#xff0c;它允许用户从下拉列表中选择一个选项。这个控件在需要用户从预定义选项中进行选择时非常有用。 效果 代码 import sys from PyQt5.QtWidgets import QAppl…

vite创建的项目使用rem适配

下面以创建vue3.0 项目为例&#xff1a; npm init vitelatest “名称” 选择vue &#xff08;选择你所对应的语言&#xff09; 更具提示步骤执行 cd xxx npm i npm run dev 然后再项目中使用 rem 需要安装插件 第一步安装插件 npm i amfe-flexible npm i postcss-pxtorem 第二…

CS144 Checkpoint 4: interoperating in the world(2024)

分析网络路径和性能&#xff1a; mtr命令 mtr 输出的详细分析&#xff1a; mtr 162.105.253.58 命令用于结合 traceroute 和 ping 的功能&#xff0c;实时监测并分析从你的计算机到目标主机&#xff08;IP 地址 162.105.253.58&#xff0c;北京大学计算中心&#xff09;之间…

Nginx配置Referer防盗链

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 HTTP Referer是Hea…

PBOOTCMS|URL静态制作教程(已解答)

0、先解压源码文件&#xff0c;在覆盖静态文件&#xff0c;全部点是。 打开程序后台登录地址www.xxx.com(你的域名)/admin.php/Menu/index 打开程序后台--系统菜单--菜单新增&#xff08;清理缓存后重新登录账号&#xff09; &#xff08;选择父菜单&#xff0c;菜单名称&#…

ROS2+TurtleBot3+Cartographer+Nav2实现slam建图和导航

0 引言 入门机器人最常见的应用就是slam建图和导航&#xff0c;本文将详细介绍这一流程&#xff0c; 便于初学这快速上手。 首先对需要用到的软件包就行简单介绍。 turtlebot3: 是一个小型的&#xff0c;基于ros的移动机器人。 学习机器人的很多示例程序都是基于turtlebot3。 …

【Java基础】枚举类的方法及应用

如何实现让一个类有固定个数的对象 手动封装构造方法&#xff08;private&#xff09; → 创建静态对象 → final修饰静态对象&#xff0c;使其成为常量 class Season { //枚举类public final static Season SPRING new Season();public final static Season SUMMER new Se…

MySQL数据库备份全攻略:从基础到高级,一文掌握所有备份技巧

在数据为王的时代&#xff0c;数据库的备份无疑是每一位数据库管理员&#xff08;DBA&#xff09;和开发者必须掌握的核心技能。MySQL作为世界上最流行的开源关系型数据库管理系统&#xff0c;其备份策略的多样性和灵活性更是值得我们深入探讨。今天&#xff0c;我们将从基础的…

废品回收微信小程序基于FastAdmin+ThinkPHP+UniApp(源码搭建/上线/运营/售后/更新)

一款基于FastAdminThinkPHPUniApp开发的废品回收系统&#xff0c;适用废品回收站、再生资源回收公司上门回收使用的小程序。 一、FastAdmin框架特色功能及优势 模块化开发&#xff1a;控制器、模型、视图、JS一一对应&#xff0c;使用RequireJS进行插件机制&#xff0c;支持插…

Java面试题:线程池的核心参数和工作原理

线程池的核心参数 ThreadPoolExecutor(int corePoolSize,//核心线程数目int MaximumPoolSize,//最大线程数核心线程临时线程long keepAliveTime,//临时线程的存活时间,在存活时间内如果没有新任务,线程资源会被释放TimeUnit unit,//存活时间的时间单位,一个枚举类型BlockingQu…

sql操作、发送http请求和邮件发送 全栈开发之路——后端篇(2)

全栈开发一条龙——前端篇 第一篇&#xff1a;框架确定、ide设置与项目创建 第二篇&#xff1a;介绍项目文件意义、组件结构与导入以及setup的引入。 第三篇&#xff1a;setup语法&#xff0c;设置响应式数据。 第四篇&#xff1a;数据绑定、计算属性和watch监视 第五篇 : 组件…

STL介绍及使用场景分析

一.总体介绍 STL&#xff08;Standard Template Library&#xff09;是C标准模板库&#xff0c;提供了一系列的通用模板类和函数&#xff0c;用于实现常见的数据结构和算法&#xff0c;方便开发者快速地实现各种功能。STL包括了容器&#xff08;Containers&#xff09;、算法&a…

[BJDCTF 2020]easy_md5、[HNCTF 2022 Week1]Interesting_include、[GDOUCTF 2023]泄露的伪装

目录 [BJDCTF 2020]easy_md5 ffifdyop [SWPUCTF 2021 新生赛]crypto8 [HNCTF 2022 Week1]Interesting_include php://filter协议 [GDOUCTF 2023]泄露的伪装 [BJDCTF 2020]easy_md5 尝试输入一个1&#xff0c;发现输入的内容会通过get传递但是没有其他回显 观察一下响应…

文本协议中嵌入二进制数据

在文本协议中嵌入二进制数据时&#xff0c;通常不推荐使用new String(byte[], Charset)&#xff0c;除非你确定这些字节实际上是以指定的字符集编码的文本。这是因为如果字节不是有效的文本编码&#xff0c;那么使用new String(byte[], Charset)可能会产生不可预测的结果&#…