数据结构之队列

devtools/2024/10/24 21:53:52/

Hello,各位小伙伴们上期我们学习了栈这样的数据结构,今天让我们一起学习一下它的孪生兄弟队列。

队列的基本概念和结构

概念:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) ​
入队列:进行插入操作的一端称为队尾 ​
出队列:进行删除操作的一端称为队头
队列底层结构选型
队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。

队列的实现

队列的基本结构:

typedef int QNDatatype;
typedef struct QueueNode
{QNDatatype data;struct QueueNode* next;
}QueueNode;//这里实在定义队列的节点
//同时要定义队列的节点指针----队列的结构
typedef struct Queue
{QueueNode* phead;//队头QueueNode* ptail;//队尾
}

 队列的结点结构与链表类似,但队列要满足基本从一端入队列,从另一端出队列如果我们像链表那样在头节点进行结点的删除,尾节点进行节点的增加,我们需要遍历链表来找到尾结点这样时间复杂度就变为O(n),所以我们额外定义了一个结构体变量在链表的两端固定头结点和尾结点。

实现队列我们要实现一下基本功能:

//队列的初始化
void QueueInit(Queue* ps);
//判断队列是否为空
bool QueueEmpty(Queue* ps);
//判断队列有效数据个数
int QueueNumSize(Queue* ps);
//入队列
void QueuePush(Queue* ps, QNDatatype x);
//删除队列节点
void QueuePop(Queue* ps);
//取对头数据
QNDatatype QueueFront(Queue* ps);
//取队尾数据
QNDatatype QueueBack(Queue* ps);
//队列的销毁
void QueueDestory(Queue* ps);

1.队列的初始化

oid QueueInit(Queue* ps)
{assert(ps);ps->phead = ps->ptail = NULL;ps->size = 0;
}

2.判断队列是否为空

bool QueueEmpty(Queue* ps)
{assert(ps);return ps->phead == NULL;//如果为空bool则会显示true
}

3.判断队列中有效数据的个数

int QueueNumSize(Queue* ps)
{int size = 0;QueueNode* pur = ps->phead;while (pur){size++;pur = pur->next;}return size;
}

在这里我们可以了解到时间复杂度为O(n),为了降低 时间复杂度我们可以在队列的结构体中多设置一个参数,int size 在入队列和出队列的时候我们只需要对ps->size加加或者减减就可以了,这样我们在此函数中直接返回ps->size即可。这样时间复杂度就会降低为O(1)。

4.入队列

在入队列操作时我们要注意在进行新的内存空间申请时注意变量类型,因为队列结点结构,我们在队列结点结构上进行了重定义,这里一定要注意一下万万不可写成队列结构。

void QueuePush(Queue* ps, QNDatatype x)
{assert(ps);QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));if (newnode == NULL){perror("malloc fail!");exit(1);}newnode->data = x;newnode->next = NULL;//将申请好的节点空间赋值并间下一个节点指针赋值为NULL//队列为空的情况下if (ps->phead == NULL){ps->phead = ps->ptail = newnode;}else {//队列不为空的情况下ps->ptail->next = newnode;//将newnode插入到尾节点的下一个节点ps->ptail = ps->ptail->next;//同时将尾节点的下一个节点置为尾节点}
}

5.删除队列结点

删除队列结点我们要注意结点个数,通过结点个数来分情况。但结点个数为1的时候队列的phead与ptail在同一个位置,直接free掉即可。

但结点个数有多个时,我们要在头结点的位置开始删除,但要创建一个新的变量next来记录头结点的下一个结点(否则如果直接删除了头结点就早不到下一个结点了)删除该结点后将next赋值给该队列的头结点。

void QueuePop(Queue* ps)
{assert(ps);assert(!QueueEmpty(&ps));//只有一个节点if (ps->phead->next == NULL){free(ps->phead);ps->phead = ps->ptail = NULL;}//多个节点的情况else {Queue* next = ps->phead->next;free(ps->phead);ps->phead = next;}}

6.取对头数据

取对头数据我们要进行两次断言,一次为传递过来的队列的指针不能为空,第二个为传递过来的队列里面的结点不能为空!然后直接返回头结点的数据即可。

QNDatatype QueueFront(Queue* ps)
{assert(ps);assert(!QueueEmpty(&ps));return ps->phead->data;
}

7.取队尾数据

QNDatatype QueueBack(Queue* ps)
{assert(ps);assert(!QueueEmpty(&ps));return ps->ptail->data;
}

8.队列的销毁

队列的销毁与链表的销毁类似,我们要循环销毁,创建一个新的队列结点结构体变量来记录队列的头结点,通过判断该结点是否为NULL来循环销毁结点。最后要记得将队列的两个指针释放掉。

void QueueDestory(Queue* ps)
{assert(ps);QueueNode* pur = ps->phead;while (pur){QueueNode* next = pur->next;free(pur);pur = next;}ps->phead = ps->ptail = NULL;
}


http://www.ppmy.cn/devtools/128521.html

相关文章

2024软考网络工程师笔记 - 第4章.局域网和城域网

文章目录 局域网基础1️⃣局域网和城域网体系架构 IEEE(负责链路层)2️⃣局域网拓扑结构 🕑CSMA/CD1️⃣CSMA/CD2️⃣CSMA/CD三种监听算法3️⃣冲突检测原理 🕒二进制指数退避算法1️⃣ 二进制指数退避算法 🕓最小帧长…

【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (五):POST上传文件的设置

本项目旨在学习如何快速使用 nodejs 开发后端api,并为以后开展其他项目的开启提供简易的后端模版。(非后端工程师) 由于文档是代码写完之后,为了记录项目中需要注意的技术点,因此文档的叙述方式并非开发顺序&#xff0…

云曦10月13日awd复现

一、防御 1、改用户密码 passwd <user> 2、改数据库密码 进入数据库 mysql -uroot -proot 改密码 update mysql.user set passwordpassword(新密码) where userroot; 查看用户信息密码 select host,user,password from mysql.user; 改配置文件&#xff0c;将密码改为自己…

算法Day-3

链表&#xff08;Linked List&#xff09; 是一种线性数据结构&#xff0c;它由一系列节点&#xff08;Node&#xff09;组成&#xff0c;每个节点包含两部分&#xff1a; 数据域&#xff1a;存储数据元素。指针域&#xff1a;存储指向下一个节点的引用&#xff08;或者是指针…

数据库实战:MySQL、SQL语句总结与应用案例分享

生活最大的危险在于一个空虚的心 文章目录 MySQLSQL语句总结 MySQL 数据库服务器数据库 (一般来说&#xff0c;一个项目&#xff0c;都会使用一个独立的数据库)数据表 (真正存储数据&#xff0c;和excel表差不多)行与列 (每一行代表一条数据&#xff0c;列又叫做字段) SQL语句…

050_python基于Python的黑龙江旅游景点数据分析系统的实现

目录 系统展示 开发背景 代码实现 项目案例 获取源码 博主介绍&#xff1a;CodeMentor毕业设计领航者、全网关注者30W群落&#xff0c;InfoQ特邀专栏作家、技术博客领航者、InfoQ新星培育计划导师、Web开发领域杰出贡献者&#xff0c;博客领航之星、开发者头条/腾讯云/AW…

分布式存储架构 与分布式一致性协议

分布式存储架构可以分为无中心节点架构和有中心节点架构。它们的设计在系统中的角色分配、数据管理、协调方式等方面有所不同。 1. 无中心节点架构&#xff08;Decentralized/Peer-to-Peer Architecture&#xff09; 在无中心节点的分布式存储架构中&#xff0c;所有节点都是…

链表(虚拟头节点)

链表 题 移除链表元素 虚拟头节点 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNode(int val, ListNode next) { this.val val; this.…