[全网最细数据结构完整版]第七篇:3分钟带你吃透队列

目录

1->队列的概念及结构

2->队列的实现

 2.1定义队列基本结构 struct QueueNode 和  struct Queue

 2.2队列初始化函数 QueueInit 函数

 2.3队列销毁函数 QueueDestroy 函数

 2.4队列插入数据函数 QueuePush 函数

 2.5判断队列是否为空,空返回true,非空返回false

 2.6队列删除数据 QueuePop 函数

 2.7获取队列头部数据 QueueFront 函数

 2.8获取队列尾部数据 QueueBack 函数

 2.9获取队列有效元素的个数 QueueSize 函数

3->测试我们自己写的栈

4->扩展知识,在Linux专栏讲解 

5->做几道选择题

6->您的专属鼓励师


1->队列的概念及结构

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

  • 入队列:进行插入操作的一端称为队尾
  • 出队列:进行删除操作的一端称为队头

2->队列的实现

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

 2.1定义队列基本结构 struct QueueNode 和  struct Queue

#pragma once//Queue.h
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>//链式结构:表示队列
typedef struct QueueNode
{struct QueueNode* _next;//指向下一个结点int _data;//数据域
}QNode;//队列的结构
typedef struct Queue
{QNode* _phead;//指向队列头部的结点QNode* _ptail;//指向队列尾部的结点int _size;//队列中结点的个数
}Queue;//1.队列初始化
void QueueInit(Queue* pq);
//2.队列销毁
void QueueDestroy(Queue* pq);
//3.队列插入数据
void QueuePush(Queue* pq, int x);
//4.队列删除数据
void QueuePop(Queue* pq);
//5.获取队列头部数据
int  QueueFront(Queue* pq);
//6.获取队列尾部数据
int  QueueBack(Queue* pq);
//7.获取队列有效元素的个数
int  QueueSize(Queue* pq);
//8.判断队列是否为空,空返回true,非空返回false
bool QueueEmpty(Queue* pq);

 2.2队列初始化函数 QueueInit 函数

//1.队列初始化
void QueueInit(Queue* pq)
{assert(pq);pq->_phead = NULL;pq->_ptail = NULL;pq->_size = 0;
}

 2.3队列销毁函数 QueueDestroy 函数

//2.队列销毁
void QueueDestroy(Queue* pq)
{assert(pq);QNode* cur = pq->_phead;while (cur != NULL){QNode* next = cur->_next;free(cur);cur = next;}pq->_phead = pq->_ptail = NULL;pq->_size = 0;
}

2.4队列插入数据函数 QueuePush 函数

//3.队列插入数据
void QueuePush(Queue* pq, int x)
{assert(pq);//申请结点QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc failed");return;}newnode->_data = x;newnode->_next = NULL;//插入数据//两种情况//1.没有结点//2.有结点if(pq->_phead == NULL && pq->_ptail == NULL){pq->_phead = pq->_ptail = newnode;}else{pq->_ptail->_next = newnode;pq->_ptail = newnode;}pq->_size++;
}

 2.5判断队列是否为空,空返回true,非空返回false

//4.判断队列是否为空,空返回true,非空返回false
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->_size == 0;
}
//5.队列删除数据
void QueuePop(Queue* pq)
{assert(pq);//得有数据才能删除对吧assert(!QueueEmpty(pq));//分为两种情况//1.只有一个结点//2.多个结点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--;
}

2.6队列删除数据 QueuePop 函数

//5.队列删除数据
void QueuePop(Queue* pq)
{assert(pq);//得有数据才能删除对吧assert(!QueueEmpty(pq));//分为两种情况//1.只有一个结点//2.多个结点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--;
}

 

2.7获取队列头部数据 QueueFront 函数

//6.获取队列头部数据
int  QueueFront(Queue* pq)
{assert(pq);assert(pq->_phead);return pq->_phead->_data;
}

2.8获取队列尾部数据 QueueBack 函数

//7.获取队列尾部数据
int  QueueBack(Queue* pq)
{assert(pq);assert(pq->_ptail);return pq->_ptail->_data;
}

 2.9获取队列有效元素的个数 QueueSize 函数

//8.获取队列有效元素的个数
int  QueueSize(Queue* pq)
{assert(pq);return pq->_size;	
}

3->测试我们自己写的栈

测试代码如下:

#include "Queue.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);while (!QueueEmpty(&q)){int num = QueueFront(&q);printf("%d->",num);QueuePop(&q);}QueueDestroy(&q);}int main()
{testQueue();return 0;
}

 看下控制台输出:欧耶!我们自己写的栈可以正常运行

4->扩展知识,在Linux专栏讲解 

另外扩展了解一下,实际中我们有时还会使用一种队列叫循环队列。如操作系统专栏讲解生产者消费者模型时可以就会使用循环队列。环形队列可以使用数组实现,也可以使用循环链表实现。
 

 

 5->做几道选择题

1.一个栈的初始状态为空。现将元素1、2、3、4、5、A、B、C、D、E依次入栈,然后再依次出栈,则元素出栈的顺序是( )。

A 12345ABCDE B EDCBA54321 C ABCDE12345 D 54321EDCBA

2.若进栈序列为 1,2,3,4 ,进栈过程中可以出栈,则下列不可能的一个出栈序列是()

A 1,4,3,2 B 2,3,4,1 C 3,1,4,2 D 3,4,2,1

3.循环队列的存储空间为 Q(1:100) ,初始状态为 front=rear=100 。经过一系列正常的入队与退队操作

后, front=rear=99 ,则循环队列中的元素个数为( )

A 1 B 2 C 99

D 0或者100

4.以下( )不是队列的基本运算?

A 从队尾插入一个新元素B 从队列中删除第i个元素C 判断一个队列是否为空

D 读取队头元素的值
5.现有一循环队列,其队头指针为front,队尾指针为rear;循环队列长度为N。其队内有效长度为?(假设

队头不存放数据)

A (rear - front + N) % N + 1

B (rear - front + N) % N

C ear - front) % (N + 1)

D (rear - front + N) % (N - 1)

答案:

1.B

2.C

3.D

4.B

5.B

 6->您的专属鼓励师

        有些事情,你永远都没有办法做到“顶尖”,因为智力跟不上.但是所有的事情,你都可以做到“高段”,因为它需要的是时间的累积和精力的打磨.不聪明与聪明之间的区别,是很微妙的.有时候我们只会通过一次两次的结果,来判断整个人、整件事,其实这是不明智的.从小,邻居和亲戚在谈论我的时候,都会觉得我很聪明。但是只有我自己知道,我从来没有聪明过,只是看上去比较聪明而已.

        修行之路确实枯燥,但是我们把问题搞懂以后就发现他是那样的美妙!一遍学不会没关系吖,多看几遍,我也是学了好多遍呢,小伙伴们肯定学的又快又好!!!最后希望写的内容对小伙伴们有所帮助,我写的如果有哪里不对的地方请在评论区或者私信指出来哦!让我们一起进步吖,任何疑问包括心情不好都可以找我聊聊,我很乐意当你的倾听者吖.   

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

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

相关文章

力扣动态规划基础版(矩阵型)

62.不同路径&#xff08;唯一路径问题&#xff09; 62. 不同路径https://leetcode.cn/problems/unique-paths/ 方法一&#xff1a;动态规划 找状态转移方程&#xff0c;也就是说它从左上角走到右下角&#xff0c;只能往右或者往下走&#xff0c;那么设置一个位置为&#xff…

Hive 实现查询用户连续三天登录记录

标题&#xff1a;Hive 实现查询用户连续三天登录记录 在数据分析和处理中&#xff0c;经常会遇到需要查询特定条件数据的情况。本文将介绍如何使用 Hive 来查询用户连续三天登录的所有数据记录。 一、问题背景 我们有一个用户登录记录表&#xff0c;其中包含用户的登录日期信…

算法(第一周)

一周周五&#xff0c;总结一下本周的算法学习&#xff0c;从本周开始重新学习许久未见的算法&#xff0c;当然不同于大一时使用的 C 语言以及做过的简单题&#xff0c;现在是每天一题 C 和 JavaScript&#xff08;还在学&#xff0c;目前只写了一题&#xff09; 题单是代码随想…

08 反射与注解

目录 1.Java类加载机制 类加载器 双亲委派模型 工作流程 优点 2.反射 基本概念 常见用法 1. 获取 Class 对象 2.获取构造方法 3.获取成员方法 4.获取成员变量 3.注解 注解的基本概念 定义和使用注解 定义注解 使用注解 解释 元注解详解 常见内置注解 总结…

【Linux第八课-进程间通信】管道、共享内存、消息队列、信号量、信号、可重入函数、volatile

目录 进程间通信为什么&#xff1f;是什么&#xff1f;怎么办&#xff1f;一般规律具体做法 匿名管道原理代码 命名管道原理代码 system V共享内存消息队列信号量信号量的接口 信号概念为什么&#xff1f;怎么办&#xff1f;准备信号的产生信号的保存概念三张表匹配的操作和系统…

Android 应用插件化及其进程关系梳理

插件应用的AndroidManifest.xml <manifest xmlns:android"http://schemas.android.com/apk/res/android"coreApp"true"package"com.demo.phone"android:sharedUserId"android.uid.phone"><uses-sdk android:minSdkVersion&q…

C# 集合与泛型

文章目录 前言1.什么是集合&#xff1f;2.非泛型集合&#xff08;了解即可&#xff09;2.1常见的非泛型集合 3.泛型的概念4.常用的泛型集合4.1 List < T > <T> <T>4.2 Dictionary<TKey, TValue>4.3 Queue < T > <T> <T>4.4 S t a c…

sql单表查询练习题

1. 查看course表结构的SQL命令是什么&#xff1f; A. SELECT * FROM exam.course; B. \d exam.course; C. \d exam.course; D. DESCRIBE exam.course; 答案&#xff1a;C 2. 使用哪个SQL命令可以查看exam.course表中的所有数据&#xff1f; A. SELECT * FROM e…

京东商品详情API接口获取(jd.item_get)和展示

获取京东商品详情 API 接口主要有以下步骤&#xff1a; 一、注册成为开发者&#xff1a; 注册账号获取key和secret&#xff0c;这是获取 API 访问权限的基础。在京东开放平台中创建一个应用&#xff0c;并填写相关信息&#xff0c;如应用程序名称、应用描述等。 二、申请 API…

数据分析-41-时间序列预测之机器学习方法XGBoost

文章目录 1 时间序列1.1 时间序列特点1.1.1 原始信号1.1.2 趋势1.1.3 季节性和周期性1.1.4 噪声1.2 时间序列预测方法1.2.1 统计方法1.2.2 机器学习方法1.2.3 深度学习方法2 XGBoost2.1 模拟数据2.2 生成滞后特征2.3 切分训练集和测试集2.4 封装专用格式2.5 模型训练和预测3 参…

【LeetCode】【算法】209. 课程表

LeetCode 209. 课程表 题目描述 你这个学期必须选修numCourses门课程&#xff0c;记为0到numCourses- 1 。 在选修某些课程之前需要一些先修课程。先修课程按数组prerequisites给出&#xff0c;其中 prerequisites[i] [a_i,b_i] &#xff0c;表示如果要学习课程a_i则必须先学…

基于大语言模型的规划

文章目录 整体框架方案生成反馈获取虽然上下文学习和思维链提示方法形式上较为简洁且较为通用,但是在面对诸如几何数学求解、游戏、代码编程以及日常生活任务等复杂任务时仍然表现不佳。为了解决这类复杂任务,可以使用基于大语言模型的规划(Planning)。该方法的核心思想在于…

【一些正经的思考】牵牛花在秋天播种可以开花吗

这是一篇正经的思考&#xff0c;因为是发生在工位上的事情&#xff0c;所以这也是上班记录~ 我入职新公司已经两个月了&#xff0c;和部门的新伙伴出去吃饭的频率高了1000%&#xff0c;不得不说&#xff0c;这边的食堂确实不是那么好吃&#xff0c;就和小伙伴经常去一个在江边…

零基础Java第十四期:继承与多态(二)

目录 一、继承 1.1. 继承的方式 1.2. final关键字 1.3. 继承与组合 1.4. protected关键字 二、多态 2.1. 多态的概念 2.2. 向上转型 2.3. 重写 2.4. 向下转型 2.5. 多态的优缺点 一、继承 1.1. 继承的方式 猫类可以继承动物类&#xff0c;中华田园猫类可以继承猫类…

Django 详细入门介绍

Django 详细入门介绍 1. 什么是 Django&#xff1f; Django 是一个开源的、用 Python 编写的 Web 框架。它遵循了“快速开发”和“不要重复自己”&#xff08;DRY&#xff09;的设计原则&#xff0c;旨在简化复杂的 Web 开发。Django 提供了多种强大的功能模块&#xff0c;如…

RabbitMQ 不公平分发介绍

RabbitMQ 是一个流行的开源消息代理软件&#xff0c;它实现了高级消息队列协议&#xff08;AMQP&#xff09;。在 RabbitMQ 中&#xff0c;消息分发策略对于系统的性能和负载均衡至关重要。默认情况下&#xff0c;RabbitMQ 使用公平分发&#xff08;Fair Dispatch&#xff09;策…

WebRTC REMB算法

WebRTC REMB&#xff08;Receiver Estimated Maximum Bitrate&#xff09;是一种带宽估计算法&#xff0c;用于在WebRTC中动态地调整视频发送端的码率&#xff0c;以适应网络带宽的变化。以下是对WebRTC REMB的详细解释&#xff1a; 一、定义与原理 定义&#xff1a;REMB是一…

RocketMQ 广播消息

所谓的广播消息就是发送的一条消息会被多个消费者收到。 ⼴播是向主题&#xff08; topic &#xff09;的所有订阅者发送消息。订阅同⼀个 topic 的多个消费者&#xff0c;能全量收到⽣产者发送的所有消息。 生产者发送了10个order&#xff0c;每个order里面有5个消息&#xff…

.Net IOC理解及代码实现

IOC理解 IoC(Inversion of Control)&#xff1a;即控制反转&#xff0c;这是一种设计思想&#xff0c;指将对象的控制权交给IOC容器&#xff0c;由容器来实现对象的创建、管理&#xff0c;程序员只需要从容器获取想要的对象就可以了。DI(Dependency Injection)&#xff0c;即依…

kafka面试十五题

1、kafka消息发送的流程 消息经过main线程里的拦截器&#xff08;可选&#xff09;、序列化器、分区器。分区器将数据发送到分区中&#xff0c;每个分区创建一个双端队列&#xff08;分区是在内存中完成的&#xff09;&#xff0c;内存总大小为32M&#xff0c;每个批次的大小为…