队列的实现以及队列如何实现栈

一、队列的定义

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

二、头文件以及结构设计

因为队列对头节点和尾节点使用多,所以我们用一个结构体封装出其头节点和尾节点的地址,会更加方便我们后续的操作:

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

三、.c文件的实现

1、初始化

void QueueInit(Queue* q)
{assert(q);q->_front = NULL;q->_rear = NULL;q->size = 0;
}

2、销毁

注意这个与链表的销毁很想,不能简单的只释放Queue节点,而是要通过循环将每一块申请的空间都释放(充分体现了链表的物理结构不连续)

void QueueDestroy(Queue* q)
{QNode* tmp = q->_front;while (tmp!=NULL){QNode* next = tmp->_pNext;free(tmp);tmp = next;}q->_front = q->_rear = NULL;q->size = 0;
}

 3、插入

void QueuePush(Queue* q, QDataType data)
{assert(q);QNode* tmp = (QNode*)malloc(sizeof(QNode));if (tmp == NULL){perror("malloc fail");return;}else {tmp->_data = data;tmp->_pNext = NULL;}if (q->_rear == NULL){q->_front = q->_rear = tmp;}else{q->_rear->_pNext = tmp;q->_rear = tmp;}q->size++;
}

4、出列

void QueuePop(Queue* q)
{assert(q);assert(q->_front);assert(q->size != 0);if (q->_front->_pNext == NULL)//只有一个节点{free(q->_front);q->_front = q->_rear = NULL;}else{QNode* next = q->_front->_pNext;free(q->_front->_pNext);q->_front = next;}q->size--;
}

5、访问头数据

QDataType QueueFront(Queue* q)
{assert(q);assert(q->_front);return q->_front->_data;
}

6、访问尾数据

QDataType QueueBack(Queue* q)
{assert(q);assert(q->_rear);return q->_rear->_data;
}

7、判断是否为空和获取数据个数

// 获取队列中有效元素个数
int QueueSize(Queue* q)
{assert(q);return q->size;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q)
{assert(q);return q->size == 0;
}

四、用队列实现栈

1、分析

我们知道栈是先出后进,而队列是先进先出;

为了操作简单,我们在一个队列中存储数据;当我们需要插入时,我们可以直接插入,将队列的队尾当做栈顶,而当我们要出数据时,我们可以将前n个数据移动到第二个队列中,最后一个在原队列中出(此时最后一个数据为第一个数据,符合先进先出);

有了以上的思路,那么这道题就非常容易解决了:

2、实现

这里要注意力扣上关于这个函数

它返回的是一个栈这个与初始化不一样。不能再函数内部直接创建栈变量,而是malloc申请一块空间后返回该指针(因为局部变量出函数就自动销毁了)

typedef struct {Queue q1;Queue q2;
} MyStack;MyStack* myStackCreate() {MyStack*psk=(MyStack*)malloc(sizeof(MyStack));QueueInit(&(psk->q1));QueueInit(&(psk->q2));return psk;
}void myStackPush(MyStack* obj, int x) 
{if(!QueueEmpty(&(obj->q1))){QueuePush(&(obj->q1),x);}else{QueuePush(&(obj->q2),x);}
}int myStackPop(MyStack* obj) 
{Queue* tmp=&(obj->q1);//假设p1为空Queue* ntmp=&(obj->q2);//p2不为空if(!QueueEmpty(&(obj->q1))){tmp=&(obj->q2);ntmp=&(obj->q1);//假设p1为空}while(QueueSize(ntmp)>1){QueuePush(tmp,QueueFront(ntmp));QueuePop(ntmp);}int top=QueueFront(ntmp);QueuePop(ntmp);return top;
}int myStackTop(MyStack* obj) 
{if(!QueueEmpty(&(obj->q1))){return QueueBack(&(obj->q1));}else{return QueueBack(&(obj->q2));}
}bool myStackEmpty(MyStack* obj) {return QueueEmpty(&(obj->q1))&&QueueEmpty(&(obj->q2));
}void myStackFree(MyStack* obj) {QueueDestroy(&obj->q1);QueueDestroy(&obj->q2);free(obj);
}

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

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

相关文章

20240507 ubuntu20.04+ros noetic 跑通lioslam

任务&#xff1a;跑通lioslam 主要参考博客 IMU激光雷达融合使用LIO-SAM建图学习笔记——详细、长文、多图、全流程_ubuntu_AIDE回归线-GitCode 开源社区 (csdn.net) 1.不要用这一句 wget -O ~/Downloads/gtsam.zip https://github.com/borglab/gtsam/archive/4.0.0-alpha2…

【Spring】初识 Spring AOP(面向切面编程)

目录 1、介绍AOP 1.1、AOP的定义 1.2、AOP的作用 1.3、AOP的核心概念及术语 2、AOP实现示例 3、EnableAspectJAutoProxy注解 1、介绍AOP 1.1、AOP的定义 AOP&#xff08;Aspect Orient Programming&#xff09;&#xff0c;直译过来就是面向切面编程&#xff0c;AOP 是一…

Windows Python 安装准备

首先安装配置 1. 环境的安装和配置: 运行环境: 官方提供了cpython解释器 编辑环境: 课程初级阶段:推荐大家使用: 记事本工具(UE、notepad++、editplus、sublime、vscode) 中期阶段IDE的使用,pycharm 2. 安装python环境: 在官方下载python解释器 www.python.org …

Ubuntu18.04--虚拟机配置Samba并从Windows登录

前言&#xff1a; 本文记录我自己在Windows上安装 Virtualbox &#xff0c;并在Virtualbox中安装 Ubuntu-18.04 虚拟机&#xff0c;在Ubuntu-18.04虚拟机里安装配置Smaba服务器&#xff0c;从 Windows 宿主系统上访问虚拟机共享samba目录的配置命令。 引用: N/A 正文 虚拟…

[C++][数据结构]哈希3:unordered_map和unordered_set的模拟实现

前言 今天我们来试着用哈希封装一下unordered_map和unordered_set这两个容器 由于主要的哈希的模拟实现都在之前的文章中&#xff0c;所以本文只是对于几个小问题进行说明 KeyOfT&#xff1a;取出key 因为我们传的第二个模板参数是T&#xff0c;我们不知道他是key还是pair&l…

Three.js的材质Material信息

Material材质信息,是独立于物体顶点之外,与渲染效果相关的属性。比如通过设置材质可以改变物体的颜色、纹理贴图、光照模式等等。 基本材质【BasicMaterial】 基本材质BasicMaterial的物体,颜色不会因为光照产生明暗、阴影效果。如果没有指定的材质颜色,那么颜色就是随机…

协同过滤的一些理解

协同过滤的一些理解 以下是我对协同过滤的一些理解&#xff0c;欢迎来交。 什么是协同过滤 协同过滤&#xff1a;利用相似用户的行为或相似商品的特征来进行推荐。 协同过滤&#xff08;Collaborative Filtering, CF&#xff09;是推荐系统中一种常用的技术&#xff0c;它基于…

揭秘LLMOps,高效开发大型语言模型

大家好&#xff0c;随着人工智能&#xff08;AI&#xff09;的蓬勃发展&#xff0c;一个新兴领域语言模型运维&#xff08;LLMOps&#xff09;正逐渐成为关注的焦点。LLMOps专注于对大型语言模型&#xff08;LLMs&#xff09;&#xff0c;例如OpenAI的GPT系列&#xff0c;进行全…

SpringBoot Actuator未授权访问漏洞的解决方法

1. 介绍 Spring Boot Actuator 是一个用于监控和管理 Spring Boot 应用程序的功能模块。它提供了一系列生产就绪的功能&#xff0c;帮助你了解应用程序的运行状况&#xff0c;以及在运行时对应用程序进行调整。Actuator 使用了 Spring MVC 来暴露各种 HTTP 或 JMX 端点&#x…

【机器学习】卷积神经(CNN)在图像识别中的革命性应用:自动驾驶的崛起

卷积神经网络&#xff08;CNN&#xff09;在图像识别中的革命性应用&#xff1a;自动驾驶的崛起 一、卷积神经网络&#xff08;CNN&#xff09;的基本原理二、CNN在图像识别中的显著成果三、CNN在自动驾驶汽车中的物体检测和识别四、CNN在图像识别中的代码实例 随着人工智能和深…

轮式机器人简介

迄今为止,轮子一般是移动机器人学和人造交通车辆中最流行的运动机构。它可达到很高的效率, 如图所示, 而且用比较简单的机械就可实现它的制作。 另外,在轮式机器人设计中,平衡通常不是一个研究问题。 因为在所有时间里,轮式机器人一般都被设计成在任何时间里所有轮子均与地接…

大模型系列之解读MoE

Mixtral 8x7B 的推出&#xff0c; 使我们开始更多地关注 基于MoE 的大模型架构&#xff0c; 那么&#xff0c;什么是MoE呢&#xff1f; 1. MoE溯源 MoE的概念起源于 1991 年的论文 Adaptive Mixture of Local Experts&#xff08;https://www.cs.toronto.edu/~hinton/absps/jjn…

间隔采样视频的代码

项目统计模型准确率 项目会保存大量视频&#xff0c;为了统计模型的精度&#xff0c;我们想要十五分钟抽取一个视频用来统计。 import os import shutil from datetime import datetime, timedelta #抽取视频的代码&#xff0c;会在每个小时的0分、15分、30分、45分取一个命名…

c++ 和c回调混合的一种实现

代码 #include <iostream> #include <list>using namespace std; struct CallbackBase { virtual void operator()(const char* msg,int len) 0; };void messagesCB(const char* msg,int len) {std::cout<<msg<<" "<<len<<std…

中国土壤类型空间分布数据

中国土壤类型空间分布数据根据全国土壤普查办公室1995年编制并出版的《1&#xff1a;100万中华人民共和国土壤图》数字化生成&#xff0c; 采用了传统的“土壤发生分类”系统&#xff0c;基本制图单元为亚类&#xff0c;共分出12土纲&#xff0c;61个土类&#xff0c;227个亚类…

JavaScript原理篇——Promise原理及笔试题实战演练

Promise 是 JavaScript 中用于处理异步操作的对象&#xff0c;它代表了一个可能还没有完成的操作的最终完成或失败&#xff0c;以及其结果值。Promise 对象有三种状态&#xff1a; Pending&#xff08;进行中&#xff09;&#xff1a;初始状态&#xff0c;既不是成功&#xff0…

JavaScript BOM - 浏览器对象模型

BOM&#xff08;浏览器对象模型&#xff09;是JavaScript中与浏览器交互的一组API&#xff0c;它提供了一种方法来操作浏览器窗口和文档。BOM由一组对象组成&#xff0c;这些对象允许您访问浏览器本身的功能&#xff0c;而不仅仅是网页内容。 BOM对象包括&#xff1a; window对…

融知财经:期货和现货的区别是什么?哪个风险大?

期货和现货在交易对象等方面存在明显的区别。期货交易是一种衍生金融工具&#xff0c;主要用于价格发现、风险管理和投机&#xff0c;而现货交易则是商品和服务的实际买卖。在选择进行期货交易还是现货交易时&#xff0c;投资者需要根据自己的需求和市场情况来决定。 期货和现货…

二叉搜索树 题解 二叉搜索树的构建 DFS

二叉搜索树 题目描述 判断两序列是否为同一个二叉搜索树序列。 输入描述 第一行是一个数 n ( 1 < n < 20 )&#xff0c;表示有 n 个二叉搜索树序列需要判断。 接下去一行是一个序列&#xff0c;序列长度小于 10 &#xff0c;包含 0 ~ 9 的数字&#xff0c;没有重复数…

【Android】Kotlin学习之Lambda表达式

java和kotlin对比 Lambda语法 Lambda隐形参数 it 也可以不使用指定的名称it, 可以 自定义 Lambda 使用下划线