数据结构:7、队列

一、队列的概念与结构

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头,如下图。

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。

二、队列的实现

1、队列的初始化与销毁

这个思路是,先创建一个节点用来存储数据,也就是一个单链表,而这里需要头和尾,也就是尾进头出,如1 2 3 4 5 6 7 这样进去,出去也是1 2  3 4 5 6 7,顺序不会改变,所以这里又定义了一个结构用来存储头和尾以及有效的数据,方便后续操作,初始化这里就是把头和尾指向空,当有数据进来时才指向新的节点,销毁就是把单链表释放销毁,而刚开始使用存储链表的头和尾的结构体,因为是局部变量,只需要把头和尾的指针置空,当函数销毁时,这个结构体也会销毁,代码如下。

typedef int QDataType;
// 链式结构:表示队列 
typedef struct QueueNode
{struct QueueNode* next;QDataType data;}QNode;// 队列的结构 
typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}Queue;
// 初始化队列 
void QueueInit(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}
// 销毁队列 
void QueueDestroy(Queue* pq)
{assert(pq);QNode* cur = pq->phead;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->phead = pq->ptail = NULL;pq->size = 0;
}

2、队列的入队与出队

这个队列是尾进头出,也就相当于尾插头删,但是需要考虑到链表中没有数据时的情况,也就是尾插时没有数据,会插入一个数据,第二个就是正常的尾插,而头删就需要考虑没有数据时,就直接释放了,代码如下。

// 队尾入队列 
void QueuePush(Queue* pq, QDataType data)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");return;}newnode->data = data;newnode->next = NULL;if (pq->ptail == NULL){assert(pq->phead==NULL);pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}// 队头出队列 
void QueuePop(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));if (pq->phead->next == NULL){free(pq->phead);pq->phead = pq->ptail = NULL;}else{QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->size--;
}

3、判断与获取首尾元素与队列内有效元素

这个就是利用之前创建的结构体可以判断下链表里有没有数据,如果有可以直接返回,之前定义的数据个数也就是可以直接看出链表有多少数据,判断也就可以直接判断有多少数据,但是不能在删除时不能忘记把数据个数减减。

// 获取队列头部元素 
QDataType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->phead->data;
}// 获取队列队尾元素 
QDataType QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->ptail->data;
}// 获取队列中有效元素个数 
int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->size==0;
}

4、测试与测试结果

这个就是测试各个函数,也就是插入1 2 3 4 5 6 7然后读取下有几个数据,然后把尾部数据打印,利用之前写的判断函数也就可以直接用while函数去进行出队数据并且打印,然后队里数据全部出完后,再去取数据打印和删除,会直接报错,代码和测试结果如图。

#define _CRT_SECURE_NO_WARNINGS 1
#include "QL.h"void TestQueue()
{Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);QueuePush(&q, 5);QueuePush(&q, 6);QueuePush(&q, 7);printf("size:%d\n", QueueSize(&q));printf("%d\n", QueueBack(&q));while (!QueueEmpty(&q)){printf("%d ", QueueFront(&q));QueuePop(&q);}printf("%d ", QueueFront(&q));QueuePop(&q);QueueDestroy(&q);
}int main()
{TestQueue();return 0;
}

三、代码

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "QL.h"void TestQueue()
{Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);QueuePush(&q, 5);QueuePush(&q, 6);QueuePush(&q, 7);printf("size:%d\n", QueueSize(&q));printf("%d\n", QueueBack(&q));while (!QueueEmpty(&q)){printf("%d ", QueueFront(&q));QueuePop(&q);}printf("%d ", QueueFront(&q));QueuePop(&q);QueueDestroy(&q);
}int main()
{TestQueue();return 0;
}

QL.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "QL.h"// 初始化队列 
void QueueInit(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}// 队尾入队列 
void QueuePush(Queue* pq, QDataType data)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");return;}newnode->data = data;newnode->next = NULL;if (pq->ptail == NULL){assert(pq->phead==NULL);pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}// 队头出队列 
void QueuePop(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));if (pq->phead->next == NULL){free(pq->phead);pq->phead = pq->ptail = NULL;}else{QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->size--;
}// 获取队列头部元素 
QDataType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->phead->data;
}// 获取队列队尾元素 
QDataType QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->ptail->data;
}// 获取队列中有效元素个数 
int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->size==0;
}// 销毁队列 
void QueueDestroy(Queue* pq)
{assert(pq);QNode* cur = pq->phead;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->phead = pq->ptail = NULL;pq->size = 0;
}

QL.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
typedef int QDataType;
// 链式结构:表示队列 
typedef struct QueueNode
{struct QueueNode* next;QDataType data;}QNode;// 队列的结构 
typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}Queue;// 初始化队列 
void QueueInit(Queue* pq);
// 队尾入队列 
void QueuePush(Queue* pq, QDataType data);
// 队头出队列 
void QueuePop(Queue* pq);
// 获取队列头部元素 
QDataType QueueFront(Queue* pq);
// 获取队列队尾元素 
QDataType QueueBack(Queue* pq);
// 获取队列中有效元素个数 
int QueueSize(Queue* pq);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* pq);
// 销毁队列 
void QueueDestroy(Queue* pq);

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

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

相关文章

漫途桥梁结构安全监测方案,护航桥梁安全!

桥梁作为城市生命线的重要组成部分&#xff0c;承载着城市交通、物流输送、应急救援等重要职能。然而&#xff0c;随着我国社会经济的飞速发展&#xff0c;桥梁所承载的交通流量逐年增长&#xff0c;其安全性所面临的挑战亦日益严峻。例如恶劣的外部环境、沉重的荷载以及长期使…

memmove函数及其模拟实现

一、用法 memmove用于拷贝字节&#xff0c;如果目标区域和源区域有重叠的话&#xff0c;memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中&#xff0c;但复制后源内容会被更改。但是当目标区域与源区域没有重叠则和memcpy函数功能相同。 二、原型&#xff1a…

Linux下安装Android Studio及创建桌面快捷方式

下载 官网地址&#xff1a;https://developer.android.com/studio?hlzh-cn点击下载最新版本即可 安装 将下载完成后文件&#xff0c;进行解压&#xff0c;然后进入android-studio-2023.2.1.23-linux/android-studio/bin目录下&#xff0c;启动studio.sh即可为了更加方便的使…

MySQL学习Day32——数据库备份与恢复

在任何数据库环境中&#xff0c;总会有不确定的意外情况发生&#xff0c;比如例外的停电、计算机系统中的各种软硬件故障、人为破坏、管理员误操作等是不可避免的&#xff0c;这些情况可能会导致数据的丢失、 服务器瘫痪等严重的后果。存在多个服务器时&#xff0c;会出现主从服…

Codeforces Round 825 D. Equal Binary Subsequences 【思维】

D. Equal Binary Subsequences 题意 给定一个长度为 2 n 2n 2n 的 01 01 01 字符串 s s s&#xff0c;现在需要恰好使用一次下面的操作&#xff0c;将其划分为相等的两个子序列 定义操作&#xff1a; 选择某些下标&#xff0c;并这些下标代表的子序列向右循环移动一位 如…

SSA-LSTM多输入分类预测 | 樽海鞘优化算法-长短期神经网络 | Matlab

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、算法介绍&#xff1a; 四、完整程序下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平台编译&am…

图像处理与图像分析—图像统计特性的计算(纯C语言实现灰度值显示)

根据输入的灰度图像&#xff0c;分别计算图像的均值、方差等统计特征&#xff0c;并计算图像的直方图特征并以图形方式显示图像的直方图&#xff08;用C或C语言实现&#xff09;。 学习将会依据教材图像处理与图像分析基础&#xff08;C/C&#xff09;版内容展开 在上个笔记中&…

C语言排序算法

int main() { int i; int arr[]{49,38,65,97,76,13,27,49}; int nsizeof(arr)/sizeof(arr[0]); //数据开始的排列 for(i0;i<n;i) { printf("%d ",arr[i]); } printf("\n"); //排序后 InsertSort(arr,n…

机器学习-0X-神经网络

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中神经网络算法。 本门课程的目标 完成一个特定行业的算法应用全过程&#xff1a; 懂业务会选择合适的算法数据处理算法训练算法调优算法融合 算法评估持续调优工程化接口实现 参考 机器学习定义 关于机…

GEE错误——Layer 2: Tile error: Reprojection output too large (10277x10480 pixels).

错误 Layer 2: Tile error: Reprojection output too large (10277x10480 pixels). Layer 2: Tile error: Reprojection output too large (10150x10479 pixels). Output of image computation is too large (18 bands for 3150625 pixels = 240.4 MiB > 80.0 MiB). 如果我…

Oracle P6 负浮时和必须完成日期

前言 学习过计划的人大都有这有这样的经历&#xff0c;即无论是Microsoft Project 亦或是P6见过负浮时那么 Primavera P6 计划中的负浮时是从何而来的呢&#xff0c;那么本文可能会有所帮助。 首先&#xff0c;当活动的最晚日期早于最早日期时&#xff0c;就会出现负浮时。 换…

Linux动态追踪——ftrace

目录 摘要 1 初识 1.1 tracefs 1.2 文件描述 2 函数跟踪 2.1 函数的调用栈 2.2 函数调用栈 2.3 函数的子调用 3 事件跟踪 4 简化命令行工具 5 总结 摘要 Linux下有多种动态追踪的机制&#xff0c;常用的有 ftrace、perf、eBPF 等&#xff0c;每种机制适应于不同的场…

uniapp h5 部署

uniapp 配置 服务器文件路径 打包文件结构 //nginx 配置 server {listen 8300;server_name bfqcwebsiteapp;charset utf-8;#允许跨域请求的域&#xff0c;* 代表所有add_header Access-Control-Allow-Origin *;#允许带上cookie请求add_header Access-Control-Allow-C…

docker harbor.v2.9.2搭建镜像无法下载问题解决

在通过部署docker harbor时&#xff0c;采用的是离线包的方式&#xff0c;当解压压缩包后&#xff0c;执行prepare脚本步骤中有一步是要获取prepare:v2.9.2版本镜像 结果执行脚本时报如下错误&#xff1a; Unable to find image goharbor/prepare:v2.9.2 locally 这时候我们就…

算法思想总结:二分查找算法

创作不易&#xff0c;感谢三连&#xff01;&#xff01; 一、二分查找算法思路总结 大家先看总结&#xff0c;然后再根据后面的题型去慢慢领悟 二、二分查找&#xff08;easy&#xff09; . - 力扣&#xff08;LeetCode&#xff09;二分查找 思路&#xff1a;&#xff08;模…

每日学习笔记:C++ STL 的forward_list

定义 特点 操作函数 元素查找、移除或安插 forward_list::emplace_after arg...指的是元素构造函数的参数&#xff08;0~N个&#xff09; #include <iostream> #include <memory> #include <list> #include <forward_list> using namespace std;class…

海思3516将BT1120改BT656输出大小为720*576

sample_comm_vi.c结构体 VI_DEV_ATTR_S DEV_ATTR_BT656D1_1MUX VI_DEV_ATTR_S DEV_ATTR_BT656D1_1MUX {/* interface mode */VI_MODE_BT656,/* multiplex mode */VI_WORK_MODE_1Multiplex,/* r_mask g_mask b_mask*/{0xFF0000, 0x0},//掩码根据自己实际写/* progess…

基于YOLOv8深度学习的野外火焰烟雾检测系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标检测

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

如何有效避免团队内耗,提升团队整体效能

团队内耗是一个普遍存在的问题&#xff0c;它可能导致工作效率低下、沟通不畅、成员间的信任缺失&#xff0c;甚至可能导致整个团队的崩溃。 它可能源于成员间的误解、利益冲突&#xff0c;或是个人情绪的波动。 如何避免团队内耗&#xff0c;是每个团队管理者和成员都应该关…

java组合模式揭秘:如何构建可扩展的树形结构

组合模式&#xff08;Composite Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许将对象组合成树形结构以表示整体/部分层次结构。组合模式使得客户端可以统一对待单个对象和组合对象&#xff0c;从而使得客户端可以处理更复杂的结构。 组合模式的主要组成部分包括&…