【不太正常的题】LeetCode.232:用栈的函数接口实现队列

🎁个人主页:我们的五年

🔍系列专栏:初阶数据结构刷题

🎉欢迎大家点赞👍评论📝收藏⭐文章

🚗  1.问题描述:

 题目中说了只能使用两个栈实现队列,并且只能使用基本的栈操作。比如:在栈顶进行入栈操作,在栈顶进行出栈,取栈顶元素,还有判空这些基本的栈操作函数。然后使用这些函数实现队列的基本操作,队列的特点就是在队尾插入数据,在队头删除数据,在对头取数据。

题中说使用两个栈实现,也给了我们提示。

🚗  2.问题分析:

假如先在一个栈中插入三元素1.2.3。

当使用StackPush函数在PushST进行三次插入以后,就变成了上面的情形,但是如果我们要进行队列取队头的数据,进行队列删除队头的数据,我们就要先把上面的3和2拿走。从而我们就想到了把左边栈里面的元素的放到右边去。

进行上面的操作以后,我们就调用栈的取栈顶的函数就可以拿到元素1,也可以进行取删除元素1,就可以达到和队列一样的性质:先进先出。

插入数据的时候,我们还是在PushST中插入数据,加入先插入4,5.

如果要进行删除操作,取元素操作也是可以直接在PopST栈中直接取。也是满足队列的要求的。但是当我们把PopST的元素都取完以后,我们就要再一次把PushST栈里面的元素导到PopST栈里面。

按照上面的步骤就可以实现队列的操作。

🚗 3.代码层面进行解析:

栈的函数接口

先给出栈的接口:

typedef int SLDataType;

typedef struct Stack{

            SLDataType* a;

            int top;

            int capacity;

}Stack;

//对栈进行初始化

void StackInit(Stack* ptr);

//对栈进行销毁

void StackDestroy(Stack* ptr);

//在栈顶插入元素

void StackPush(Stack* ptr, SLDataType x);

//获取栈顶元素

SLDataType StackTop(Stack* ptr);

//对栈进行判断,如果为空,返回true,否则返回false

bool StackEmpty(Stack* ptr);

//销毁栈的栈顶元素

void StackPop(Stack* ptr);

用栈的函数实现队列

先定义我自己结构体的类型:

根据上面分析也是用两个栈实现队列,也就是说我的队列类型中保护了两个栈,并且我把这两个队列命名为PushST和PopST

typedef struct {Stack PushST;        //把元素新的元素放在这个栈,也就是在这个栈里面实现插入操作Stack PopST;         //在这个栈中取数据,删除数据} MyQueue;

创建队列,在堆区上申请一块空间,并且对队列里面的栈进行初始化

MyQueue* myQueueCreate() {MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));StackInit(&obj->PushST);      //对PushST和PopST栈进行初始化  StackInit(&obj->PopST);return obj;}

取队头元素

int myQueuePeek(MyQueue* obj) {if(StackEmpty(&obj->PopST))    //PopST栈为空的时候就要把PushST栈里面的元素导过来{while(!StackEmpty(&obj->PushST))    //导元素{int Pop=StackTop(&obj->PushST);StackPop(&obj->PushST);StackPush(&obj->PopST,Pop);}}return StackTop(&obj->PopST);    返回PopST栈顶的元素
}

销毁队头元素,并且返回队头元素。首先应该保存PopST栈的栈顶元素,然后销毁栈顶元素。

一个特别巧妙的点就是,我们在进行取队头元素的时候,如果PopST为空,取队头元素函数就会把PushST里面的元素导到PopST里面,这样我们在myQueuePop中就避免了导元素这一步骤。

int myQueuePop(MyQueue* obj) {int top=myQueuePeek(obj);    //取队头元素StackPop(&obj->PopST);return top;
}

 最后的push函数和判空函数还有销毁函数也是比较简单的

//直接在PushST队列中进行插入
void myQueuePush(MyQueue* obj, int x) {StackPush(&obj->PushST,x);
}//队列判空,当队列里面的两个队列都为空时才为空
bool myQueueEmpty(MyQueue* obj) {return StackEmpty(&obj->PopST)&&StackEmpty(&obj->PushST);
}//销毁队列
void myQueueFree(MyQueue* obj) {StackDestroy(&obj->PopST);StackDestroy(&obj->PushST);
}

🚗 最终代码:

typedef int SLDataType;typedef struct Stack{SLDataType* a;int top;int capacity;
}Stack;//对栈进行初始化
void StackInit(Stack* ptr);//对栈进行销毁
void StackDestroy(Stack* ptr);//在栈顶插入元素
void StackPush(Stack* ptr, SLDataType x);//获取栈顶元素
SLDataType StackTop(Stack* ptr);//对栈进行判断,如果为空,返回true,否则返回false
bool StackEmpty(Stack* ptr);void StackPop(Stack* ptr);//栈的初始化
void StackInit(Stack* ptr)
{assert(ptr);ptr->a = NULL;ptr->capacity = ptr->top = 0;
}//销毁栈
void StackDestroy(Stack* ptr)
{assert(ptr);free(ptr->a);ptr->a = NULL;ptr->capacity = ptr->top = 0;	//初始化时,top=0,表示指向栈顶的下一个元素
}//在栈顶插入元素
void StackPush(Stack* ptr, SLDataType x)
{assert(ptr);if (ptr->top == ptr->capacity){int newcapacity = ptr->capacity == 0 ? 4 : ptr->capacity * 2;SLDataType* tmp = (SLDataType*)realloc(ptr->a, newcapacity*sizeof(SLDataType));if (tmp == NULL){perror("realloc fail");return;}ptr->a = tmp;ptr->capacity = newcapacity;}ptr->a[ptr->top++] = x;
}//取栈顶元素
SLDataType StackTop(Stack* ptr)
{assert(ptr);assert(!StackEmpty(ptr));return ptr->a[ptr->top - 1];
}//栈判空
bool StackEmpty(Stack* ptr)
{assert(ptr);return ptr->top == 0;
}//销毁栈顶元素
void StackPop(Stack* ptr)
{assert(ptr);assert(!StackEmpty(ptr));ptr->top--;
}typedef struct {Stack PushST;Stack PopST;
} MyQueue;MyQueue* myQueueCreate() {MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));StackInit(&obj->PushST);StackInit(&obj->PopST);return obj;
}void myQueuePush(MyQueue* obj, int x) {StackPush(&obj->PushST,x);
}int myQueuePop(MyQueue* obj) {int top=myQueuePeek(obj);StackPop(&obj->PopST);return top;
}int myQueuePeek(MyQueue* obj) {if(StackEmpty(&obj->PopST)){while(!StackEmpty(&obj->PushST)){int Pop=StackTop(&obj->PushST);StackPop(&obj->PushST);StackPush(&obj->PopST,Pop);}}return StackTop(&obj->PopST);
}bool myQueueEmpty(MyQueue* obj) {return StackEmpty(&obj->PopST)&&StackEmpty(&obj->PushST);
}void myQueueFree(MyQueue* obj) {StackDestroy(&obj->PopST);StackDestroy(&obj->PushST);
}/*** Your MyQueue struct will be instantiated and called as such:* MyQueue* obj = myQueueCreate();* myQueuePush(obj, x);* int param_2 = myQueuePop(obj);* int param_3 = myQueuePeek(obj);* bool param_4 = myQueueEmpty(obj);* myQueueFree(obj);
*/

 

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

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

相关文章

Linux搭建text-generation-webui框架,安装通义千问大模型,开放对外api,voxta测试对话图文教程

目录 text-generation-webui部分 开放对外API 通义千问部分 远程API对话测试部分 text-generation-webui部分 本来不想发这个文章的,但是自己部署的时候看了挺多人的帖子,很多发的不全面,要么就是跟着他们流程走有些小问题啥的&#xff…

QT程序发布后,mysql在其它电脑设备无法连接数据库

QT程序发布后,mysql在其它电脑设备无法连接数据库 D:\mysql-5.7.24-winx64\lib, mysql-5.7.24-winx64是一个压缩包,用于启动mysql服务,创建数据库 压缩包 解决方法: 拷贝库到exe的相同目录,libmysql.dll,libmysql.li…

Nginx单向链表 ngx_list_t

目录 基本概述 数据结构 接口描述 具体实现 ngx_list_create ngx_list_init ngx_list_push 使用案例 整理自 nginx 1.9.2 源码 和 《深入理解 Nginx:模块开发与架构解析》 基本概述 Nginx 中的 ngx_list_t 是一个单向链表容器,链表中的每一个节…

软件项目需求分析的实践探索(1)

一、项目启动与规划 组建团队 包括项目经理、系统分析师、业务分析师以及可能涉及的最终用户代表和领域专家等。例如,开发一个医疗管理软件,就需要有医疗行业的专家参与,确保对医疗业务流程有深入理解。明确各成员的职责,如系统分…

网络管理-期末项目(附源码)

环境:网络管理 主机资源监控系统项目搭建 (保姆级教程 建议点赞 收藏)_搭建网络版信息管理系统-CSDN博客 效果图 下面3个文件的项目目录(python3.8.8的虚拟环境) D:\py_siqintu\myproject5\Scripts\mytest.py D:\py_siqintu\myproject5\Sc…

MySQL 常用程序介绍

以下是一些常用的MySQL程序: 程序名作⽤mysqldMySQL的守护进程即 MySQL 服务器,要使⽤MySQL 服务器 mysqld必须正在运⾏状态mysql MySQL客⼾端程序,⽤于交互式输⼊ SQL 语句或以批处理模式从⽂件执⾏SQL的命令⾏⼯具 mysqlcheck⽤于检查、修…

Redis篇--常见问题篇4--大Key(Big Key,什么是大Key,影响及使用建议)

1、概述 大Key:通常是指值(Value)的长度非常大,实际上键(Key)长度很大也算。通常来说,键本身不会很长,占用的内存较少,因此判断一个键是否为bigKey主要看它对应的值的大…

ModbusTCP从站转Profinet主站案例

一. 案例背景 在复杂的工业自动化场景中,企业常常会采用不同品牌的设备来构建生产系统。西门子SINAMICS G120变频器以其高性能、高精度的速度和转矩控制功能,在电机驱动领域应用广泛。施耐德M580可编程逻辑控制器则以强大的逻辑控制和数据处理能力著称&…

微信小程序-基于Vant Weapp UI 组件库的Area 省市区选择

Area 省市区选择,省市区选择组件通常与 弹出层 组件配合使用。 areaList 格式 areaList 为对象结构,包含 province_list、city_list、county_list 三个 key。 每项以地区码作为 key,省市区名字作为 value。地区码为 6 位数字,前两…

智驾感知「大破局」!新一轮混战开启

随着智能驾驶搭载率的攀升,舱外传感器赛道迎来新变局。 一方面,从近几年智驾传感器的配置变化来看,摄像头的主导地位显而易见。 12月10-12日,由德赛西威总冠名的2024(第八届)高工智能汽车年会暨年度金球奖…

Kibana8.17.0在mac上的安装

1、Kibana是什么 Kibana是与elasticsearch配套使用的数据分析与可视化工具,通过Kibana可以轻松与es中存储的数据进行高效的交互,包括数据写入、检索、删除等操作,并可以通过编写部分代码将数据做成各种报表,从而进行非常直观的统…

数字IC后端设计实现十大精华主题分享

今天小编给大家分享下吾爱IC社区星球上周十大后端精华主题。 Q1:星主,请教个问题,长tree的时候发现这个scan的tree 的skew差不多400p,我高亮了整个tree的schematic,我在想是不是我在这一系列mux前边打断,设置ignore p…

给bmp和png,设置BLENDFUNCTION的AlphaFormat不同参数的效果

BLENDFUNCTION是AlphaBlend用控制透明效果的重要参数。 选择一个32位的png图片,设置AlphaFormat 为 AC_SRC_ALPHA,效果如上图。 选择一个32位的png图片,设置AlphaFormat 为 0,效果如上图。 选择一个24位的bmp图片,设置…

ChildLife“童年时光杯”足球联赛启动 共促青少年健康成长

2024年12月21日至22日,由美国知名婴幼儿营养品牌ChildLife童年时光赞助的“童年时光杯”青少年足球联赛将在上海拉开帷幕。本次赛事U7/U8组别共有16支足球队参赛,包括上海幸运星足球俱乐部旗下的明星球队,以及其他青少年俱乐部的优秀队伍&…

MTK--mt7921 usb wifi debug

文章目录 1、代码编译2、配置文件修改3、Wifi设置命令4、Wifi debug 淘宝随便买个7921的usb wifi。 1、代码编译 export TEMPLATECONF${PWD}/meta/meta-mediatek-mt8518/conf/base/aud8518sp2-slc-32b-7921-c4a-user source meta/poky/oe-init-build-env bitbake mtk-image-au…

如何配置OSB连接数据连接/读取超时

1.Oracle DB OSB中的DBAdapter的查询超时参数配置没用,要解决接口超时问题,需要在console中的数据源配置超时参数: oracle.net.CONNECT_TIMEOUT30000 oracle.net.READ_TIMEOUT30000 添加图片注释,不超过 140 字(可选…

一起学Git【第六节:查看版本差异】

git diff是 Git 版本控制系统中用于展示差异的强大工具。他可以用于查看文件在工作区、暂存区和版本库之间的差异、任意两个指定版本之间的差异和两个分支之间的差异等,接下来进行详细的介绍。 1.显示工作区与暂存区之间的差异 # 显示工作区和暂存区之间的差异,后面不加参数…

Python数据处理——re库与pydantic的使用总结与实战,处理采集到的思科ASA防火墙设备信息

目录 Python正则表达式re库的基本用法 引入re库 各函数功能 总结 使用方法举例 正则表达式语法与书写方式 正则表达式的常用操作符 思科ASA防火墙数据 数据1 数据2 书写正则表达式 Python中pydantic的使用 导入基础数据模板 根据数据采集目标定义Pydantic数据类型…

`we_chat_union_id IS NOT NULL` 和 `we_chat_union_id != ‘‘` 这两个条件之间的区别

文章目录 1、什么是空字符串?2、两个引号之间加上空格 好的,我们来详细解释一下 we_chat_union_id IS NOT NULL 和 we_chat_union_id ! 这两个条件之间的区别,以及它们在 SQL 查询中的作用: 1. we_chat_union_id IS NOT NULL 含…

如何利用AWS监听存储桶并上传到tg bot

业务描述: 需要监听aws的存储中的最新消息,发送新的消息推送到指定tg的频道。 主要流程: 1.上传消息到s3存储桶(不做具体描述) 2.通过aws的lambda监听s3存储桶的最新消息(txt文件) 3.将txt文件…