leetcode:225. 用队列实现栈

news/2024/7/24 9:46:02 标签: leetcode, 算法, 职场和发展

一、题目

链接:225. 用队列实现栈 - 力扣(LeetCode)

函数原型:

typedef struct { 

} MyStack;

MyStack* myStackCreate() 

void myStackPush(MyStack* obj, int x) 

int myStackPop(MyStack* obj) 

int myStackTop(MyStack* obj) 

bool myStackEmpty(MyStack* obj) 

void myStackFree(MyStack* obj) 

二、思路

利用队列实现栈:

1.我的栈的结构

“我的栈”是一个结构体,存放两个队列即可

2.我的栈创建及其初始化

函数返回值是“我的栈”结构体指针,动态申请一个“我的栈”大小内存空间,然后初始化“我的栈”结构体中中的两个队列,最后返回“我的栈”的结构体指针

3.我的栈入栈

“我的栈”中有两个队列,选择一个空队列进行存储数据。由于栈的入栈和队列的入队都是从尾部进行存储数据的,所以直接对空队列进行入队操作即可。

如何找到空队列?

利用假设法,假设q1为空队列,q2为非空队列;判断q1是否为空,如果不为空,则将空队列设为q2,非空队列设为q1.

4.我的栈出栈

由于栈删除元素是从栈顶删除,而队列删除元素是从队头删除,所以需要先将非空队列中的前n-1个元素出队并入队到空队列中,第n个元素直接出队无需入队。即可完成“我的栈”的出栈。

5.我的栈取栈顶元素

取栈顶元素是在栈尾部进行的,所以可以对非空队列的取队尾元素。

6.我的栈判空

只要对两个队列判空即可,只有当两个队列都为空时,“我的栈”才判断为空。

7.我的栈销毁

首先对“我的栈”中两个队列进行队列销毁,然后再对动态申请的“我的栈”空间进行动态内存释放。

三、代码

typedef int QDataType;

//队列的结构定义
typedef struct QueueNode{
    QDataType val;
    struct QueueNode *next;
}QNode;

//用结构体管理队列
typedef struct Queue{
    QNode* phead;
    QNode* ptail;
    int size;
}Queue;

//队列的初始化
void QueueInit(Queue* pq)
{
    pq->phead=NULL;
    pq->ptail=NULL;
    pq->size=0;
}

//入队
void QueuePush(Queue *pq,QDataType x)
{
    assert(pq);
    QNode *newnode=(QNode*)malloc(sizeof(QNode));
    if(newnode==NULL)
    {
        perror("malloc fail");
        exit(-1);
    }
    newnode->val=x;
    newnode->next=NULL;
    if(pq->phead==NULL)//队列为空
        pq->phead=pq->ptail=newnode;
    else
    {
        pq->ptail->next=newnode;
        pq->ptail=newnode;
    }
    pq->size++;
}

//出队
void QueuePop(Queue* pq)
{
    assert(pq);
    assert(pq->phead);//空队列

    if(pq->phead==pq->ptail)
    {
        pq->ptail=NULL;
    }
    QNode* tmp=pq->phead;
    pq->phead=tmp->next;
    free(tmp);
    tmp=NULL;
    pq->size--;
}

//取队头元素
QDataType QueueFront(Queue* pq)
{
    assert(pq);
    assert(pq->phead);
    return pq->phead->val;
}

//取队尾元素
QDataType QueueBack(Queue* pq)
{
    assert(pq);
    assert(pq->ptail);
    return pq->ptail->val;
}

//判空
bool QueueEmpty(Queue *pq)
{
    assert(pq);
    return pq->phead==NULL;
}

//销毁队列
void QueueDestroy(Queue* pq)
{
    assert(pq);
    QNode *cur=pq->phead;
    while(cur)
    {
        QNode* tmp=cur;
        cur=cur->next;
        free(tmp);
        tmp=NULL;
    }
    pq->phead=pq->ptail=NULL;
    pq->size=0;
}

typedef struct {
    Queue q1;
    Queue q2;
} MyStack;

//我的栈创建及其初始化
MyStack* myStackCreate() {
    MyStack *ps=(MyStack*)malloc(sizeof(MyStack));
    QueueInit(&ps->q1);
    QueueInit(&ps->q2);

    return ps;
}

void myStackPush(MyStack* obj, int x) {
    //利用假设法
    Queue *empty=&obj->q1;
    Queue *noneempty=&obj->q2;
    if(!QueueEmpty(&obj->q1))
    {
        empty=&obj->q2;
        noneempty=&obj->q1;
    }

    QueuePush(noneempty,x);
    //QueuePush(&obj->q1,x);
}

//我的栈-出栈
int myStackPop(MyStack* obj) {

    // while(obj->q1.size>1)
    // {
    //     QueuePush(&obj->q2,QueueFront(&obj->q1));
    //     QueuePop(&obj->q1);
    //     //QueuePush(&obj->q2,QueuePop(&obj->q1));
    // }
    // int stackpop=QueueFront(&obj->q1);
    // QueuePop(&obj->q1);

    // while(obj->q2.size)
    // {
    //     QueuePush(&obj->q1,QueueFront(&obj->q2));
    //     QueuePop(&obj->q2);
    //     //QueuePush(&obj->q1,QueuePop(&obj->q2));
    // }

    // return stackpop;

    //利用假设法
    Queue *empty=&obj->q1;
    Queue *noneempty=&obj->q2;
    if(!QueueEmpty(&obj->q1))
    {
        empty=&obj->q2;
        noneempty=&obj->q1;
    }

    while(noneempty->size>1)
    {
        QueuePush(empty,QueueFront(noneempty));
        QueuePop(noneempty);
    }
    int stackpop=QueueFront(noneempty);
    QueuePop(noneempty);
    return stackpop;
}

//我的栈-出栈
int myStackTop(MyStack* obj) {
    Queue* empty=&obj->q1;
    Queue* noneempty=&obj->q2;
    if(!QueueEmpty(&obj->q1))
    {
        empty=&obj->q2;
        noneempty=&obj->q1;
    }
    return QueueBack(noneempty);
}

//我的栈-判空
bool myStackEmpty(MyStack* obj) {
    return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);
}

//我的栈-销毁
void myStackFree(MyStack* obj) {
    QueueDestroy(&obj->q1);
    QueueDestroy(&obj->q2);
    free(obj);
}

/**
 * Your MyStack struct will be instantiated and called as such:
 * MyStack* obj = myStackCreate();
 * myStackPush(obj, x);
 
 * int param_2 = myStackPop(obj);
 
 * int param_3 = myStackTop(obj);
 
 * bool param_4 = myStackEmpty(obj);
 
 * myStackFree(obj);
*/


http://www.niftyadmin.cn/n/5234405.html

相关文章

鸿蒙(HarmonyOS)HelloWo入门

1.HarmonyOS简单介绍 1. HarmonyOS特征:一开发发,多端部署,可分可合,自由流转2. HarmonyOS使用的语言:是ArkTs,ArkTs是在TypeScript(简称TS)基础上扩展的,而TS又是在JavaScript(简称JS)的超集、UI框架ArkUI…

【高效开发工具系列】jackson入门使用

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

php时间和centos时间不一致

PHP 时间和 CentOS 操作系统时间不一致的问题通常是由于时区设置不同造成的。解决这个问题可以通过以下几个步骤: 检查 CentOS 系统时间: 你可以通过在终端运行命令 date 来查看当前的系统时间和时区。 配置 CentOS 的时区: 如果系统时间不正…

【PTA-C语言】实验三-循环结构I

如果代码存在问题,麻烦大家指正 ~ ~有帮助麻烦点个赞 ~ ~ 实验三-循环结构I 7-1 求交错序列前N项和 (分数 15)7-2 寻找250(分数 15)7-3 最大公约数和最小公倍数(分数 15)7-4 统计字符&#xff0…

基础Python教程之读写sqlite

前言 SQLite 是一种嵌入式数据库管理系统,它是一个自包含、零配置的、服务器无关的数据库引擎。它的设计目标是提供一个轻量级的、高效的数据库解决方案,适用于嵌入式系统、移动设备和简单的应用程序。 Python 是一种高级编程语言,其强大的标…

iRDMA流量控制总结 - 1

1.0 内容简介 This will introduce Ethernet flow control on Intel Ethernet 800 Series Network Adapters with RDMA driver - iRDMA, with a focus on best practices for Linux RDMA traffic. 我们将介绍英特尔以太网 800 系列网络适配器上的以太网流量控制与 RDMA 驱动程序…

线程安全的问题以及解决方案

线程安全 线程安全的定义 线程安全:某个代码无论是在单线程上运行还是在多线程上运行,都不会产生bug. 线程不安全:单线程上运行正常,多线程上运行会产生bug. 观察线程不安全 看看下面的代码: public class ThreadTest1 {public static int count 0;public static void main…

【CTA认证】Android8实现android6以下的应用运行时也要申请权限

需求 CTA入网认证,要求低版本比如Android6以下的应用,运行时,也需要有运行时权限(Runtime Permission)功能,不能默认就取到权限,必须人工在设置中打开才可。 环境 Android 8 实现 frameworks 修改思路是所有APP都…