OJ:用栈实现队列

232. 用栈实现队列 - 力扣(LeetCode)

总体思路 

思路:由于C语言阶段没有相对应的栈库,所以我们需要手搓一个栈,再在此基础上来实现这道题,题目所由多个接口函数所构成 ,在开始写代码前,我们需要在自己的队列结构中创建两个栈变量,因为经过分析我们发现,我们定义两个栈分别进行删除和插入操作是非常完美的。

typedef struct {
    Stack Pushl;
    Stack Popl;
} MyQueue;

再有了这个之后,我们需要为他开辟空间,从而进行下面的操作,这里使用malloc开辟空间,并且初始化结构体中的两个栈,当然如果你构造的结构体里面是两个指针的话,首先会出现野指针问题,因为指针不赋值的话就是野指针了,还有就是你定义的是指针,你用malloc开辟空间时并没有开辟了空间,反而是开辟了指针。这里如果你非得想用指针的话,在下面的初始化接口中还得传递二级指针,因为你想改变这个指针嘛!这里为了简单,所以我们定义的是两个常量。

MyQueue* myQueueCreate() {
    MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));

    StackInit(&obj->Pushl);
    StackInit(&obj->Popl);
    return obj;
}

 

然后我们继续实现接口函数,我们来看插入函数,对插入来说,我们左侧就单纯执行插入

 


void myQueuePush(MyQueue* obj, int x) {
    StackPush(&obj->Pushl,x);
}

接下来我们写的并不是删除,我们写的是peek()这个接口,也就是返回顶部元素,对上图来说如果右侧有值的话,并且也没有删除的话,那栈顶就是1,那就直接取就好了是吧,但是如果右侧为空时,我们得先判断左侧是否有值,如果有,得把值给右侧。然后再取右侧的栈顶。

int myQueuePeek(MyQueue* obj) {
    if(StackEmpty(&obj->Popl))
    {
       
            while(!StackEmpty(&obj->Pushl))
            {
                int top=STTop(&obj->Pushl);
                StackPop(&obj->Pushl);
                StackPush(&obj->Popl,top);
            }
       
    }
    return STTop(&obj->Popl);
}

接下来就是pop函数了,还是那句话,就是如果pop有值,就直接删除,倘若没有值,就看左侧,如果左侧有值就移动到右侧,再删除,这段话是不是有点耳熟,跟上面peek函数功能中有些类似,所以借用peek函数。

int myQueuePop(MyQueue* obj) {
    int top=myQueuePeek(obj);
    StackPop(&obj->Popl);
    return top;
}

 对与判断他是否为空和销毁,判断是否为空呢,就是左右两侧必须都为空才为空,销毁时,记得先销毁结构体中的两个栈常量。

bool myQueueEmpty(MyQueue* obj) {
    return StackEmpty(&obj->Pushl)&&StackEmpty(&obj->Popl);
}

void myQueueFree(MyQueue* obj) {
    StackDestroy(&obj->Pushl);
    StackDestroy(&obj->Popl);
    free(obj);
}

在oj中呢,是不用写头文件的 

代码

//支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;//栈
	int capacity;//容量
}Stack;

//初始化栈
void StackInit(Stack* ps);
//入栈
void StackPush(Stack* ps, STDataType data);
//出栈
void StackPop(Stack* ps);
//获取栈中有效元素个数
int StackSize(Stack* ps);
//检测栈中是否为空,如果为空返回非零结果,如果不为空返回0
int StackEmpty(Stack* ps);
//获取栈顶元素
STDataType STTop(Stack* ps);
//销毁栈
void StackDestroy(Stack* ps);

//初始化栈
void StackInit(Stack* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}
//入栈
void StackPush(Stack* ps, STDataType data)
{
	assert(ps);

	if (ps->capacity == ps->top)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}

	ps->a[ps->top++] = data;
}
//出栈
void StackPop(Stack* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
zzzzz
	ps->top--;
}
//获取栈中有效元素个数
int StackSize(Stack* ps)
{
	assert(ps);
	return ps->top;
}
//检测栈中是否为空,如果为空返回非零结果,如果不为空返回0
int StackEmpty(Stack* ps)
{
	assert(ps);
	return ps->top == 0;
}
//获取栈顶元素
STDataType STTop(Stack* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));

	return ps->a[ps->top - 1];
}
//销毁栈
void StackDestroy(Stack* ps)
{
	assert(ps);

	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}


typedef struct {
    Stack Pushl;
    Stack Popl;
} MyQueue;


MyQueue* myQueueCreate() {
    MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));

    StackInit(&obj->Pushl);
    StackInit(&obj->Popl);
    return obj;
}

void myQueuePush(MyQueue* obj, int x) {
    StackPush(&obj->Pushl,x);
}

int myQueuePop(MyQueue* obj) {
    int top=myQueuePeek(obj);
    StackPop(&obj->Popl);
    return top;
}

int myQueuePeek(MyQueue* obj) {
    if(StackEmpty(&obj->Popl))
    {
       
            while(!StackEmpty(&obj->Pushl))
            {
                int top=STTop(&obj->Pushl);
                StackPop(&obj->Pushl);
                StackPush(&obj->Popl,top);
            }
       
    }
    return STTop(&obj->Popl);
}

bool myQueueEmpty(MyQueue* obj) {
    return StackEmpty(&obj->Pushl)&&StackEmpty(&obj->Popl);
}

void myQueueFree(MyQueue* obj) {
    StackDestroy(&obj->Pushl);
    StackDestroy(&obj->Popl);
    free(obj);
}

/**
 * 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.mfbz.cn/a/426049.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv9独家原创改进|使用DySample超级轻量的动态上采样算子

专栏介绍:YOLOv9改进系列 | 包含深度学习最新创新,主力高效涨点!!! 一、DySample论文摘要 尽管最近的基于内核的动态上采样器如CARAFE、FADE和SAPA取得了令人印象深刻的性能提升,但它们引入了大量的工作量&…

实时抓取SKU商品属性详细信息API数据接口(淘宝,某音)

item_sku-获取sku详细信息 taobao.item_sku详细信息 API公共参数 请求地址: https://api-gw.onebound.cn/taobao/item_sku 名称类型必须描述keyString是调用key(演示示例)secretString是调用密钥api_nameString是API接口名称(包括在请求地…

芯来科技发布最新NI系列内核,NI900矢量宽度可达512/1024位

参考:芯来科技发布最新NI系列内核,NI900矢量宽度可达512/1024位 (qq.com) 本土RISC-V CPU IP领军企业——芯来科技正式发布首款针对人工智能应用的专用处理器产品线Nuclei Intelligence(NI)系列,以及NI系列的第一款AI专用RISC-V处理器CPU IP…

机器人 标准DH与改进DH

文章目录 1 建立机器人坐标系1.1 连杆编号1.2 关节编号1.3 坐标系方向2 标准DH(STD)2.1 确定X轴方向2.2 建模步骤2.3 变换顺序2.4 变换矩阵3 改进DH(MDH)3.1 确定X轴方向3.2 建模步骤3.3 变换顺序3.4 变换矩阵4 标准DH与改进DH区别5 Matlab示例参考链接1 建立机器人坐标系 1.1…

现代化数据架构升级:毫末智行自动驾驶如何应对年增20PB的数据规模挑战?-OceanBase案例

毫末智行是一家致力于自动驾驶的人工智能技术公司,其前身是长城汽车智能驾驶前瞻分部,以零事故、零拥堵、自由出行和高效物流为目标,助力合作伙伴重塑和全面升级整个社会的出行及物流方式。 在自动驾驶领域中,是什么原因让毫末智行…

边缘智能网关:让环境监测更智能

在环境监测领域,边缘智能网关可用于区域环境的实时监测、分析和预警,例如河湖水位监测、雨雪监测、风沙/风速监测,通过实时采集并分析环境变化数据,能够有助于对于突发、急发的各种自然灾害进行快速预警和应对。 一、边缘智能网关…

Docker 创建容器并指定时区

目录 1. 通过环境变量设置时区(推荐)2. 挂载宿主机的时区文件到容器中3. 总结 要在 Docker 容器中指定时区,可以通过两种方式来实现: 1. 通过环境变量设置时区(推荐) 在 Docker 运行时,可以通…

Unity UI实现表格渲染

前言 最近有在用Unity做前端UI, 用到了实现表格数据渲染,也就是后台给的list渲染到表格中,查看了许多资料发现比较少,因此在这里记录一下吧,希望可以帮助到大家哦。 也是第一次使用Unity,先简单介绍一下&…

类构造完成,Bean注入之后执行方法

PostConstruct 容器执行之后执行 PreDestory 在容器销毁之前执行

redis进阶(一)

文章目录 前言一、Redis中的对象的结构体如下:二、压缩链表三、跳跃表 前言 Redis是一种key/value型数据库,其中,每个key和value都是使用对象表示的。 一、Redis中的对象的结构体如下: /** Redis 对象*/ typedef struct redisO…

今日arXiv最热大模型论文:谷歌最新研究,将LLM用于回归分析任务,显著超越传统模型

回归分析是一个强大的工具,能够准确预测系统或模型的结果指标,给定一组参数。然而,传统上这些方法仅适用于特定任务。本文研究者提出了OMNIPRED框架,这是一个训练语言模型作为通用端到端回归器的框架,它可以处理来自多…

SNAP:如何批量预处理Sentinel2 L2A数据集并输出为TIFF文件?

我的需求 我目前就是希望下载哨兵2号数据,然后在SNAP中进行批量提取真彩色波段并输出为TIFF文件。 数据集下载说明 目前哨兵网站似乎进行了一大波更新,连网站都换了,网址如下: https://dataspace.copernicus.eu/ 打开后界面如…

五千字 DDL、DML、DQL、DCL 超详解

SQL语句,根据其功能,主要分为四类:DDL、DML、DQL、DCL。 DDL (Data Definition Language) 数据定义语言,用来定义数据库对象(数据库,表, 字段) DML (Data Manipulation Languag) 数据操作语言,…

想从事数据方向职场小白看过来, 数据方面的一些英文解释

想从事数据方向职场小白看过来,一些英文名词解释 文章目录 想从事数据方向职场小白看过来,一些英文名词解释 英文类解释NoSQL:ESB:ACID :Data Vault:MDM:OLAP:SCD:SBA:MP…

从嵌入式Linux到嵌入式Android

最近开始投入Android的怀抱。说来惭愧,08年就听说这东西,当时也有同事投入去看,因为恶心Java,始终对这玩意无感,没想到现在不会这个嵌入式都快要没法搞了。为了不中年失业,所以只能回过头又来学。 首先还是…

Python算法100例-2.11 换分币

完整源代码项目地址,关注博主私信源代码后可获取 1.问题描述2.问题分析3.算法设计4.确定程序框架5.完整的程序6.运行结果 1.问题描述 将5元的人民币兑换成1元、5角和1角的硬币,共有多少种不同的兑换方法。 2.问题分析 根据该…

【框架】Spring 框架重点解析

Spring 框架重点解析 1. Spring 框架中的单例 bean 是线程安全的吗? 不是线程安全的 Spring 框架中有一个 Scope 注解,默认的值是 singleton,即单例的;因为一般在 Spring 的 bean 对象都是无状态的(在生命周期中不被…

嵌入式Qt 对话框及其类型 QDialog

一.对话框的概念 对话框是与用户进行简短交互的顶层窗口。 QDialog是Qt中所有对话框窗口的基类。 QDialog继承与QWidfet是一种容器类型的组件。 QDialog的意义: QDialog作为一种专业的交互窗口而存在。 QDialog不能作为子部部件嵌入其他容器中。 QDialog是定制…

【算法集训】基础算法:枚举

一、基本理解 枚举的概念就是把满足题目条件的所有情况都列举出来,然后一一判定,找到最优解的过程。 枚举虽然看起来麻烦,但是有时效率上比排序高,也是一个不错的方法、 二、最值问题 1、两个数的最值问题 两个数的最小值&…

力扣刷题:226.反转二叉树

题目: 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1]示例 2: 输入:root [2,1,3] 输出:[2…
最新文章