用栈实现队列

news2024/11/17 6:35:59

题目:

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

这题跟我们之前写过的 用队列实现栈 很像,感兴趣的可以自行了解一下。

题目内容

准备工作

这题明确说明了需要用栈来实现队列,介于C语言没有队列的库,所以在此之前我们需要用调用之前学的栈,详见栈

我们如果之前写过的话,直接复制过来就可以了,由于重点是讲用栈实现队列,所以这里就不过多了解栈了。

typedef int STDataType;
struct Stack
{
    STDataType* a;
    int top;       // 栈顶
    int capacity;  // 容量,方便增容
};

//typedef struct Stack ST;
typedef struct Stack Stack;

void StackInit(Stack* pst);
void StackDestroy(Stack* pst);

// 性质就决定在栈顶出入数据
void StackPush(Stack* pst, STDataType x);
void StackPop(Stack* pst);
STDataType StackTop(Stack* pst);

bool StackEmpty(Stack* pst);
int StackSize(Stack* pst);

void StackInit(Stack* pst)
{
    assert(pst);

    pst->a = (STDataType*)malloc(sizeof(STDataType) * 4);
    pst->top = 0;
    pst->capacity = 4;
}

void StackDestroy(Stack* pst)
{
    assert(pst);
    free(pst->a);
    pst->a = NULL;
    pst->capacity = pst->top = 0;
}

// 性质就决定在栈顶出入数据
void StackPush(Stack* pst, STDataType x)
{
    assert(pst);
    if (pst->top == pst->capacity)
    {
        STDataType* tmp = (STDataType*)realloc(pst->a, sizeof(STDataType)*pst->capacity * 2);
        if (tmp == NULL)
        {
            printf("realloc fail\n");
            exit(-1); // 结束整个程序
        }

        pst->a = tmp;
        pst->capacity *= 2;
    }

    pst->a[pst->top] = x;
    pst->top++;
}

void StackPop(Stack* pst)
{
    assert(pst);
    assert(!StackEmpty(pst));
    pst->top--;
}

STDataType StackTop(Stack* pst)
{
    assert(pst);
    assert(!StackEmpty(pst));

    return pst->a[pst->top - 1];
}

bool StackEmpty(Stack* pst)
{
    assert(pst);

    return pst->top == 0;
}

int StackSize(Stack* pst)
{
    assert(pst);

    return pst->top;
}

看懂题

这样之后,我们有些小伙伴觉得自己英语不好,看不懂那些函数名,从而放弃这题,其实这里和英语好不好是没有太多关系的。注意看:

我们通过返回值大概了解了,题目中函数的含义。

创建结构体

“typedef struct”这个函数,有过对数据结构的基础认识,看到“struct”肯定是创建结构体。创建出的结构体决定了我们之下来的解题思路。所以我们先来了解一下实现这题的基本思路:

用栈实现队列的基本思路

我们如此反复倒数据,每次到最后一个元素就把它pop掉,所以我们避免不了要用到两个指针,指向两个链表的指针。如此一来“typedef struct”这个函数就容易实现了。

typedef struct 
{
    //定义两个栈指针
    Stack* pop;
    Stack* push;
} MyQueue;

创建空间

MyQueue* myQueueCreate() ”我们有了结构体,一定要初始化,不初始化会导致结构体内部的值不确定,容易出错。现在最新的“vs”如果不初始化,都编译不了了。

 MyQueue* myQueueCreate() 
{
    MyQueue* ps = (MyQueue*)malloc(sizeof(MyQueue));
    if(ps == NULL)
    {
        perrof("malooc:");
        excit(-1);
    }
    //初始化
    StackInit(&obj->pop);
    StackInit(&obj->push);

    return ps;
}

入栈

这个只要我们把push里的数据导入pop里就行了。

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

出栈

上图分析了,这个要分有无数据两种情况讨论。

int myQueuePop(MyQueue* obj) 
{
    if(StackEmpty(&obj->pop))
    {
        //倒数据
        while(!StackEmpty(&obj->push))
        {
            StackPush(&obj->pop, StackTop(&obj->push));
            StackPop(&obj->push);
        }
    }
    else
    {
        StackTop(&obj->pop);
    }
}

获取元素

这里还是要分两种情况,但是我们可以取巧一点:我们假设,pop有数据的时候,我们直接取顶,或者直接调用上文写的出栈函数;pop无数据的时候,我们就倒数据,就行了。

int myQueuePeek(MyQueue* obj) {
    if (StackEmpty(&obj->pop))
    {
        while (!StackEmpty(&obj->push))
        {
            StackPush(&obj->pop, StackTop(&obj->push));
            StackPop(&obj->push);
        }
    }
    return StackTop(&obj->pop);
}

这里我们再来看上文的出栈,发现这里其实可以相互调用的。

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

这样就简化了代码。

判空

两个队列同时为空

bool myQueueEmpty(MyQueue* obj) 
{
    return StackEmpty(&obj->push) && StackDestory(&obj->pop);
}

释放空间

释放两个链表的同时,不要忘记释放两个指针,避免内存泄漏。

void myQueueFree(MyQueue* obj) 
{
    StackDestory(&obj->push);
    StackDestory(&obj->push);

    free(ps);
    ps = NULL;
}

总结

我们可以发现原理(几幅图就能搞定)都不难,主要是代码的实现,需要注意许多细节,一定要注意避免内存泄漏。

欢迎大家点赞和评论。

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

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

相关文章

Open3D 网格整形(Python版本)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 如果我们想要根据少量的约束来变形一个三角形网格,我们可以使用网格变形算法。Open3D中提供了一种ARAP整形方法,该方法的最终的目的是优化下面这个误差方程: 这里的 R i R_i R<

初识 Bootstrap4(前端开发框架)

初识 Bootstrap&#xff08;前端开发框架&#xff09;参考Bootstrap特点获取目录结构jQuery 与 Popper准备工作包含 jQuery 与 Poppermetabox-sizing基本模板无注释版本注释版本参考 项目描述Bootstrap 官方教程https://getbootstrap.net/docs/getting-started/introduction/百…

Streamlit如何展示3D模型?

Streamlit 是一个非常好的创建 web demo 的库&#xff0c;但是对于单目深度估计很难找到可以展示 3D 模型的东西。 正如我刚刚在 Jupyter Notebook 中使用 obj2html 库可视化 3D 模型所做的那样&#xff0c;我创建了一个演示&#xff1a;HuggingFacae Spaces Monocular Depth …

【算法基础】归并排序

目录 一、归并排序的思想 二、归并排序的步骤 三、归并的方式 四、代码模板 一、归并排序的思想 归并排序和快速排序一样&#xff0c;都是分治的思想。它是将一个无序的数组一分为二&#xff0c;最后再合二为一&#xff0c;将两个有序数组合并成为一个有序数组。 时间复杂…

2023兔年第一篇文章【CSS】之CSS列表详解【CSS基础知识详解】

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 本文章收录于专栏 【CSS】 【CSS专栏】已发布文章 &#x1f4c1;【CSS基础认知】 &#x1f4c1;【CSS选择器全解指南】 &#x1f4c1…

ARM S5PV210的iNand

一、iNand介绍 1、iNand/eMMC/SD Card/MMC Card 的关联 (1) 最早出现的是 MMC 卡&#xff0c;卡片式结构&#xff0c;按照 MMC 协议设计。&#xff08;相较于 NandFlash 芯片来说&#xff0c;MMC 卡有 2 个优势&#xff1a;第一是卡片化&#xff0c;便于拆装&#xff1b;第二是…

【Java开发】Spring Cloud 06 :分布式配置管理-Nacos Config

在微服务架构中&#xff0c;我们会使用一个分布式的“配置中心”来管理所有的配置文件和配置项&#xff0c;本章节将介绍 Nacos 配置中心的特性&#xff0c;以及这些特性在微服务体系中所发挥的作用。在 Spring Boot 应用中&#xff0c;我们习惯于使用传统的配置管理方式&#…

【蓝桥杯】简单数论——GCDLCM

GCD 最大公约数Greatest Common Divisor(GCD)&#xff1a;整数a和b的GCD是指能同时整除a和b的最大整数&#xff0c;记为gcd(a,b)。由于-a的因子和a的因子相同&#xff0c;因此gcd(a, b) gcd(al, |bl)。编码时只关注正整数的最大公约数。 GCD性质 (1) gcd(a, b) gcd(a, ab) g…

活动星投票教师创课大赛网络评选微信的投票方式线上免费投票

“教师创课大赛”网络评选投票_小程序不记名选举投票_投票微信创建链接_微信公众号投票制作小程序投票活动如何做&#xff1f;很多企业在运营当中&#xff0c;都会通过投票活动来进行推广&#xff0c;从而达到吸粉、增加用户粘度等效果。而此类投票活动&#xff0c;通过小程序就…

【C进阶】通讯录2.0(文末附原码)

⭐博客主页&#xff1a;️CS semi主页 ⭐欢迎关注&#xff1a;点赞收藏留言 ⭐系列专栏&#xff1a;C语言进阶 ⭐代码仓库&#xff1a;C Advanced 家人们更新不易&#xff0c;你们的点赞和关注对我而言十分重要&#xff0c;友友们麻烦多多点赞&#xff0b;关注&#xff0c;你们…

webpack搭建的React脚手架项目与vite进行兼容化开发

React项目兼容vite开发 问题描述 前言&#xff1a;之前在做Vue开发项目的过程中&#xff0c;是使用vite搭建的项目&#xff0c;不论是启动速度还是热更新&#xff0c;都非常的丝滑&#xff0c;可以极大弥补我电脑的短板&#xff0c;也提升了我的开发体验&#xff01;。 由于…

马帮对接打通金蝶云星空订单

马帮对接打通金蝶云星空获取订单列表接口与销售出库新增接口接入系统&#xff1a;马帮马帮ERP旗下有马帮ERP3.0、马帮ERP亚马逊专用版、马帮WMS仓储管理系统、马帮云仓、马帮TMS、跨境分销、马帮供应链SCM管理系统等产品&#xff0c;为跨境电商卖家提供高效管理方法和解决方案&…

【操作系统】—— 如何使用VMware虚拟机(带你快速了解)

&#x1f4dc; “作者 久绊A” 专注记录自己所整理的Java、web、sql等&#xff0c;IT技术干货、学习经验、面试资料、刷题记录&#xff0c;以及遇到的问题和解决方案&#xff0c;记录自己成长的点滴。 &#x1f341; 操作系统【带你快速了解】对于电脑来说&#xff0c;如果说…

java多态/类的组合2022023

多态 Java引用变量有两个类型&#xff1a;一个是编译时类型&#xff0c;一个是运行时类型。编译时类型由声明该变量时使用的类型决定&#xff0c;运行时类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致&#xff0c;就可能出现所谓的多态&#xff08;Polymor…

LeetCode刷题复盘笔记—一文搞懂贪心算法之55. 跳跃游戏问题(贪心算法系列第四篇)

今日主要总结一下可以使用贪心算法解决的一道题目&#xff0c;55. 跳跃游戏 题目&#xff1a;55. 跳跃游戏 Leetcode题目地址 题目描述&#xff1a; 给定一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。 数组中的每个元素代表你在该位置可以跳跃的最大长…

Python流程控制语句之选择语句

前言 在生活中&#xff0c;我们总是要做出许多选择&#xff0c;程序也是一样。比如下面的例子&#xff1a; 如果输入的用户名和密码正确&#xff0c;提示登录成功&#xff0c;否则&#xff0c;提示登录失败。如果考试成绩大于等于60分&#xff0c;则及格&#xff0c;否则不及…

在甲骨文云容器实例(Container Instances)上部署firefox

甲骨文云推出了容器实例&#xff0c;这是一项无服务器计算服务&#xff0c;可以即时运行容器&#xff0c;而无需管理任何服务器。 今天我们尝试一下通过容器实例部署firefox。 Step1. 创建容器实例 在甲骨文容器实例页面&#xff0c;单击"创建容器实例"&#xff0c…

[漏洞分析] CVE-2022-2602 io_uring UAF内核提权详细解析

本文首发于华为安全应急响应中心公众号&#xff1a; https://mp.weixin.qq.com/s/w_u0FoiFdU0KM397UXJojw 文章目录漏洞简介环境搭建漏洞原理文件引用计数与飞行计数引用计数飞行计数发送过程scm_send接收过程unix_gc垃圾处理机制io_uring原理(仅限漏洞)io_uring_setupio_urin…

零基础学JavaWeb开发(十六)之 mybatis(2)

5、MyBatis - 映射文件标签 5.1、映射文件的顶级元素 select&#xff1a;映射查询语句 insert&#xff1a;映射插入语句 update&#xff1a;映射更新语句 delete&#xff1a;映射删除语句 sql&#xff1a;可以重用的 sql 代码块 resultMap&#xff1a;最复杂&#xff0c…

11. 集合set类型详解

python3 set类型的使用 1. 基础知识 &#xff08;1&#xff09; 集合&#xff08;set&#xff09;是由一个或数个形态各异的大小整体组成的&#xff0c;构成集合的事物或对象称作元素或是成员。集合是一个无序的不重复元素序列。 &#xff08;2&#xff09;基本功能是进行成员…