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

【数据结构】队列篇

文章目录

  • 1.队列
    • 1.1 队列的概念及结构
  • 2. 队列的实现
    • 2.1 准备工作
    • 2.2 队列的初始化
    • 2.3 队尾入队列
    • 2.4 队头出队列
    • 2.5 获取队列头部元素
    • 2.6 获取队列队尾元素
    • 2.7 获取队列有效元素个数
    • 2.8 检测队列是否为空
    • 2.9 销毁队列
  • 3. 代码整合

1.队列

1.1 队列的概念及结构

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

2. 队列的实现

队列和栈一样,既可以用数组来实现也可以用链表来实现,不过因为队列不仅会用到队尾还会用到队头的特性,用链表来实现更优一些,用数组会降低效率。
入队演示
入队演示

出队演示
出队演示

2.1 准备工作

创建两个结构体,一个结构体用来维护队列的节点,一个结构体用来维护队列的首尾。
还可以在queue中再维护一个size,用来记录链表的节点数量。当然这里我没有这样写

#define Datatype int
//节点,维持队列的节点
typedef struct Node
{Datatype data;struct Node* next;
}Node;//队列,维护队列的头和尾
typedef struct Queue
{Node* front;Node* tail;
}Queue;

2.2 队列的初始化

因为初始时是没有节点的,把队列的首尾都初始化尾NULL

//初始化
void InitQueue(Queue* pq)
{assert(pq);pq->front = NULL;pq->tail = NULL;
}

2.3 队尾入队列

创建节点后开始判断,如果当前节点为空,那么我们就把队列的头和尾都指向这个新创建的节点。
如果队列已经有节点了,那么我们就把它链接的队尾的next,然后再更新队尾指针。

//队尾入队列
void PushQueue(Queue* pq, Datatype x)
{assert(pq);//创建节点Node* newnode = (Node*)malloc(sizeof(Node));if (newnode == NULL){perror("malloc");exit(-1);}newnode->data = x;newnode->next = NULL;if (pq->tail == NULL)//如果队列为空{//此时队头和队为指向同一节点pq->front = newnode;pq->tail = newnode;}else{pq->tail->next = newnode;//更新队尾指针pq->tail = newnode;}
}

2.4 队头出队列

出队列就是要删除嘛,不能是空的,为此我们加一个断言就好了。
删除队列节点时,因为是队首节点,删它前我们先要找到队首节点的下一个节点以防链表丢失,然后更新队首指针。
注意:如果队列就只有一个节点,再删除后要感谢队首和队尾指针。

//队头出队列
void PopQueue(Queue* pq)
{assert(pq);assert(pq->front);//防止队列为空if (pq->front == pq->tail){free(pq->front);pq->front = pq->tail = NULL;return;}Node* cur = pq->front->next;free(pq->front);pq->front = cur;
}

2.5 获取队列头部元素

因为队首指针存在,直接返回队首指针指向节点的值。

//获取队列头部元素
Datatype FrontQueue(Queue* pq)
{assert(pq);assert(pq->front);return pq->front->data;
}

2.6 获取队列队尾元素

因为队尾指针存在,直接返回队尾指针指向节点的值。

//获取队列队尾元素
Datatype BackQueue(Queue* pq)
{assert(pq);assert(pq->tail);return pq->tail->data;
}

2.7 获取队列有效元素个数

因为在准备阶段我们并没有用队列维护一个size,所以这里要遍历队列来求有效元素的个数。

//获取队列有效元素个数
int SizeQueue(Queue* pq)
{assert(pq);int sz = 0;Node* cur = pq->front;while (cur){sz += 1;cur = cur->next;}return sz;
}

2.8 检测队列是否为空

检测队列是否为空,如果为空返回真,否则返回假,注意别搞反了

//检测队列是否为空,如果为空返回真,否则返回假
bool EmptyQueue(Queue* pq)
{assert(pq);return pq->front == NULL;
}

2.9 销毁队列

使用了动态内存一定要记得销毁,不然会有内存泄漏的~

//销毁队列
void DestoryQueue(Queue* pq)
{assert(pq);Node* cur = pq->front;while (cur){Node* next = cur->next;free(cur);cur = NULL;cur = next;}
}

3. 代码整合

//queue.h
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>#define Datatype int
//节点,维持队列的节点
typedef struct Node
{Datatype data;struct Node* next;
}Node;//队列,维护队列的头和尾
typedef struct Queue
{Node* front;Node* tail;
}Queue;//初始化
void InitQueue(Queue* pq);//队尾入队列
void PushQueue(Queue* pq, Datatype x);//队头出队列
void PopQueue(Queue* pq);//获取队列头部元素
Datatype FrontQueue(Queue* pq);//获取队列队尾元素
Datatype BackQueue(Queue* pq);//获取队列有效元素个数
int SizeQueue(Queue* pq);//检测队列是否为空,如果为空返回真,否则返回假
bool EmptyQueue(Queue* pq);//销毁队列
void DestoryQueue(Queue* pq);//queue.c
#include "queue.h"//初始化
void InitQueue(Queue* pq)
{assert(pq);pq->front = NULL;pq->tail = NULL;
}//队尾入队列
void PushQueue(Queue* pq, Datatype x)
{assert(pq);//创建节点Node* newnode = (Node*)malloc(sizeof(Node));if (newnode == NULL){perror("malloc");exit(-1);}newnode->data = x;newnode->next = NULL;if (pq->tail == NULL)//如果队列为空{//此时队头和队为指向同一节点pq->front = newnode;pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}
}//队头出队列
void PopQueue(Queue* pq)
{assert(pq);assert(pq->front);if (pq->front == pq->tail){free(pq->front);pq->front = pq->tail = NULL;return;}Node* cur = pq->front->next;free(pq->front);pq->front = cur;
}//获取队列头部元素
Datatype FrontQueue(Queue* pq)
{assert(pq);assert(pq->front);return pq->front->data;
}//获取队列队尾元素
Datatype BackQueue(Queue* pq)
{assert(pq);assert(pq->tail);return pq->tail->data;
}//获取队列有效元素个数
int SizeQueue(Queue* pq)
{assert(pq);int sz = 0;Node* cur = pq->front;while (cur){sz += 1;cur = cur->next;}return sz;
}//检测队列是否为空,如果为空返回真,否则返回假
bool EmptyQueue(Queue* pq)
{assert(pq);return pq->front == NULL;
}//销毁队列
void DestoryQueue(Queue* pq)
{assert(pq);Node* cur = pq->front;while (cur){Node* next = cur->next;free(cur);cur = NULL;cur = next;}
}//test.c
#include "queue.h"void test1()
{//Queue q;//InitQueue(&q);//PushQueue(&q,1);//PushQueue(&q,2);//PushQueue(&q,3);//PushQueue(&q,4);//printf("%d\n", SizeQueue(&q));//printf("%d\n", BackQueue(&q));//printf("%d\n", FrontQueue(&q));//DestoryQueue(&q);
}
int main()
{test1();return 0;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【如何有效解决前端Vue中的常见难题】
  • zdpgo_gin_limit 为zdpgo_gin打造的接口限流框架,当API接口需要限制访问频率的时候可以使用此框架
  • 公主少爷都爱看的haproxy七层代理详细介绍及常见实验详解
  • 学懂C++ (十九):高级教程——深入详解C++信号处理
  • 初识C++ · C++11(2)
  • 若依 ruoyi 单体双token(url区分)
  • Linux 软件编程学习第十一天
  • 使用RPC服务的步骤
  • python打怪练习
  • UEFI ——Firmware层级结构
  • [数据集][目标检测]轴承缺陷划痕检测数据集VOC+YOLO格式1166张1类别
  • wordpress评论ip异常问题
  • 美团面经到店研发
  • 微服务的多面手:Spring Cloud 多数据中心支持全解析
  • 使用Python+moviepy保存截取视频画面
  • 08.Android之View事件问题
  • C语言笔记(第一章:C语言编程)
  • gulp 教程
  • IP路由与转发
  • Js基础知识(一) - 变量
  • Laravel Telescope:优雅的应用调试工具
  • Linux快速复制或删除大量小文件
  • ng6--错误信息小结(持续更新)
  • PHP 程序员也能做的 Java 开发 30分钟使用 netty 轻松打造一个高性能 websocket 服务...
  • Python_OOP
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • Traffic-Sign Detection and Classification in the Wild 论文笔记
  • XForms - 更强大的Form
  • 爱情 北京女病人
  • 搭建gitbook 和 访问权限认证
  • 诡异!React stopPropagation失灵
  • 紧急通知:《观止-微软》请在经管柜购买!
  • 漂亮刷新控件-iOS
  • 通信类
  • 微信小程序实战练习(仿五洲到家微信版)
  • 我感觉这是史上最牛的防sql注入方法类
  • 正则学习笔记
  • linux 淘宝开源监控工具tsar
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • # 飞书APP集成平台-数字化落地
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • (01)ORB-SLAM2源码无死角解析-(66) BA优化(g2o)→闭环线程:Optimizer::GlobalBundleAdjustemnt→全局优化
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (6) 深入探索Python-Pandas库的核心数据结构:DataFrame全面解析
  • (C)一些题4
  • (poj1.2.1)1970(筛选法模拟)
  • (Python) SOAP Web Service (HTTP POST)
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (备份) esp32 GPIO
  • (多级缓存)缓存同步
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (三)Pytorch快速搭建卷积神经网络模型实现手写数字识别(代码+详细注解)
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置