栈和队列的相互实现(C)

news/2024/6/16 19:41:45

目录

    • 1.[用栈实现队列]<https://leetcode.cn/problems/implement-queue-using-stacks/description/>
    • 2.全套代码
    • 3.[用队列实现栈]<https://leetcode.cn/problems/implement-stack-using-queues/description/>
    • 4.全套代码

1.[用栈实现队列]https://leetcode.cn/problems/implement-queue-using-stacks/description/

在这里插入图片描述

思路:

建立两个栈,pushst(只进栈),popst(只出栈)
每次进栈时都进pushst,出栈时都出popst。在出栈之前要判断栈是否为NULL,如果为空,就把pushst,倒到popst.

特别注意:栈是“后进先出”

思路图解

  • 向pushst中插入1,2,3,4
    在这里插入图片描述
  • pop掉一个数据
    在这里插入图片描述
  • push 5,6
    在这里插入图片描述
  • pop 两次
    在这里插入图片描述

2.全套代码

说明:因为是用C语言实现的,所以首先需要自己创建一个栈


//栈的创建typedef int STDataType;//提高代码的维护性typedef struct Stack
{STDataType* a;//动态int top;//栈顶int capacity;//空间大小
}ST;//栈的初始化和销毁
void STInit(ST* st);
void STDestroy(ST* st);//栈的插入和删除
void STPush(ST* st, STDataType x);
void STPop(ST* st);//取栈顶元素
STDataType Get(ST* st);//判空
bool STEmpty(ST* st);//求栈的长度
int STSize(ST* st);//栈的初始化和销毁
void STInit(ST* st)
{assert(st);st->a = NULL;st->top = st->capacity = 0;
}void STDestroy(ST* st)
{free(st->a);st->a = NULL;st->top = st->capacity = 0;
}//栈的插入和删除
void STPush(ST* st, STDataType x)
{assert(st);//如果空间不够就进行扩容if (st->capacity == st->top){int newcapacity = st->capacity == 0 ? 4 : st->capacity * 2;ST* tmp = (ST*)realloc(st->a,sizeof(STDataType) * newcapacity);if (tmp == NULL){perror("realloc");return;}//扩容成功st->a = tmp;st->capacity = newcapacity;}st->a[st->top] = x;st->top++;
}void STPop(ST* st)
{assert(st);assert(st->top > 0);st->top--;
}//取栈顶元素
STDataType Get(ST* st)
{assert(st);assert(st->top > 0);return st->a[st->top - 1];
}//判空
bool STEmpty(ST* st)
{assert(st);return st->top == 0;
}//求栈的长度
int STSize(ST* st)
{assert(st);return st->top;
}
//创建栈完成//…………………………………………………………………………………………………………………………………………………………………………………………………………………………
//定义两个栈
typedef struct {ST pushst;ST popst;
} MyQueue;MyQueue* myQueueCreate() {MyQueue* tmp=(MyQueue* )malloc(sizeof(MyQueue));STInit(&tmp->pushst);STInit(&tmp->popst);return tmp;
}void myQueuePush(MyQueue* obj, int x) {STPush(&obj->pushst,x);
}int myQueuePop(MyQueue* obj) {int top=myQueuePeek(obj);STPop(&obj->popst);return top;
}
//要想取元素,一定要让s2中存在数据
int myQueuePeek(MyQueue* obj) {if(STEmpty(&obj->popst)){while(STSize(&obj->pushst)>0){STPush(&obj->popst,Get(&obj->pushst));STPop(&obj->pushst);}}return Get(&obj->popst);
}bool myQueueEmpty(MyQueue* obj) {return STEmpty(&obj->pushst)&&STEmpty(&obj->popst);
}void myQueueFree(MyQueue* obj) {STDestroy(&obj->pushst);STDestroy(&obj->popst);free(obj);obj=NULL;
}/*** 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);
*/

3.[用队列实现栈]https://leetcode.cn/problems/implement-stack-using-queues/description/

在这里插入图片描述

思路:

创建两个空队列,q1,q2
刚开始两个队列都是空,插入数据就随便向那个里面插入。后面插入数据时,看那个队列不是空,就插入到那个队列内
删除数据时,把数据从不为空的队列,倒到为空的队列里面(只用倒前N-1个,最后一个直接pop掉)

思路图解
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4.全套代码

说明:用C语言实现,需要直接先创建一个队列

//创建队列typedef int QDataType;
//创建节点结构体
typedef struct QueueNode
{struct Queue* next;QDataType val;
}QNode;
//定义了头指针和尾指针,避免二级指针
//1.二级指针 2.带哨兵位的头节点 3.创建一个结构体,封装头,尾指针
typedef struct Queue
{QNode* phead;QNode* ptail;int size;//方便计算队列中元素个数
}Queue;//初始化,销毁
void QInint(Queue* pq);
void Qdestroy(Queue* pq);//插入,删除
void QPush(Queue* pq, QDataType x);
void QPop(Queue* pq);//求长度
int QSize(Queue* pq);//取队列头和尾的元素
QDataType GetFront(Queue* pq);
QDataType GetBack(Queue* pq);//判空
bool QEmpty(Queue* pq);//初始化,销毁
void QInint(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}void Qdestroy(Queue* pq)
{assert(pq);while (pq->phead){QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->ptail = NULL;pq->size=0;
}//插入,删除
void QPush(Queue* pq, QDataType x)
{//创建一个新的节点QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");return;}newnode->val = x;newnode->next = NULL;if (pq->ptail == NULL){pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}void QPop(Queue* pq)
{assert(pq);assert(pq->size > 0);if (pq->phead == pq->ptail)//只有一个节点{free(pq->phead);pq->phead = pq->ptail = NULL;}else//有一个以上的节点{QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}//如果直接像下面这么写,ptail就会变成野指针/*QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;*/pq->size--;
}//求长度
int QSize(Queue* pq)
{assert(pq);return pq->size;
}//取队列头和尾的元素
QDataType GetFront(Queue* pq)
{assert(pq);assert(pq->size > 0);return pq->phead->val;
}
QDataType GetBack(Queue* pq)
{assert(pq);assert(pq->size > 0);return pq->ptail->val;
}
//判空
bool QEmpty(Queue* pq)
{assert(pq);return pq->size == 0;
}
//创建队列完成
//……………………………………………………………………………………………………………………………………………………………………………………………………………………
//定义两个队列结构
//匿名结构体
typedef struct {Queue q1;Queue q2;
} MyStack;MyStack* myStackCreate() {MyStack*tmp=(MyStack*)malloc(sizeof(MyStack));QInint(&tmp->q1);//初始化QInint(&tmp->q2);return tmp;
}
//关于向队列里面插入数
//向队列不为空的里面插入数据,然后两个队列之间相互倒
void myStackPush(MyStack* obj, int x) {//假设法Queue* NoEmpty=&obj->q1,*Empty=&obj->q2;if(!QEmpty(&obj->q2)){NoEmpty=&obj->q2;Empty=&obj->q1;}QPush(NoEmpty,x);}int myStackPop(MyStack* obj) {Queue* NoEmpty=&obj->q1,*Empty=&obj->q2;if(!QEmpty(&obj->q2)){NoEmpty=&obj->q2;Empty=&obj->q1;}while(QSize(NoEmpty)>1){QPush(Empty,GetFront(NoEmpty));QPop(NoEmpty);}//现在非空链表中还剩一个元素int ret=GetFront(NoEmpty);QPop(NoEmpty);return ret;
}int myStackTop(MyStack* obj) {Queue* NoEmpty=&obj->q1,*Empty=&obj->q2;if(!QEmpty(&obj->q2)){NoEmpty=&obj->q2;Empty=&obj->q1;}return GetBack(NoEmpty);
}bool myStackEmpty(MyStack* obj) {return QEmpty(&obj->q1)&&QEmpty(&obj->q2);
}void myStackFree(MyStack* obj) {Qdestroy(&obj->q1);Qdestroy(&obj->q2);free(obj);obj=NULL;
}/*** 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.mrgr.cn/p/52383153

相关文章

【大数据】HDFS、HBase操作教程(含指令和JAVA API)

目录 1.前言 2.HDFS 2.1.指令操作 2.2.JAVA API 3.HBase 3.1.指令操作 3.2.JAVA API 1.前言 本文是作者大数据专栏系列的其中一篇&#xff0c;前文中已经详细聊过分布式文件系统HDFS和分布式数据库HBase了&#xff0c;本文将会是它们的实操讲解。 HDFS相关前文&#x…

LeetCode 题目 119:杨辉三角 II

作者介绍&#xff1a;10年大厂数据\经营分析经验&#xff0c;现任字节跳动数据部门负责人。 会一些的技术&#xff1a;数据分析、算法、SQL、大数据相关、python&#xff0c;欢迎探讨交流 欢迎加入社区&#xff1a;码上找工作 作者专栏每日更新&#xff1a; LeetCode解锁1000题…

python教程12-面向对象进阶

1、classmethod类方法 类方法只能访问类变量,不能访问实例变量2、staticmethod静态方法 不能访问类变量,也不能访问实例变量。除非在实例调用时给方法传实例。3、反射1-判断对象是否有属性的情况 用法: 实例: __name__,模块被其他模块导入的时候调用,是你叫的名字。模块自…

Windows系统完全卸载删除 Node.js (包含控制面板找不到node.js选项情况)

1.打开cmd命令行窗口&#xff0c;输入npm cache clean --force 回车执行 2.打开控制面板&#xff0c;在控制面板中把Node.js卸载 移除之后检查环境变量是否也移除&#xff1a;点击Path&#xff0c;点击编辑。 把环境变量中和node有关的全部移除&#xff0c;然后点击确定。 3.重…

Loongnix系统替换内核操作

Loongnix系统替换内核操作 一、终端下执行命令 sudo apt search linux-image* 返回结果中格式如: linux-image-4.19.0-19-loongson-3 为最新的内核源码。 二、下载内核源码包 sudo apt source linux-image-4.19.0-19-loongson-3 如提示&#xff1a;E: 您必须在 sources.li…

宝塔docker快速安装Halo

宝塔docker快速安装Halo 一、Docker 部署Halo 我们前面还是需要先在宝塔面板环境中安装Docker,一般默认时候是没有安装的。这里我们在宝塔面板中的Docker管理器应用商店中安装。我们可以看到直接等待安装成功。后面在部署程序的时候有需要用到这里界面。二、这里我们在【镜像管…

环形链表(给定一个链表的头节点 head ,返回链表开始入环的第一个节点)的原理讲解

一&#xff1a;题目 二&#xff1a;原理讲解 解决这个题目 &#xff0c;我们得先理解它的原理。 1&#xff1a; 首先假设两个指针&#xff0c;一个快指针fast&#xff0c;一个慢指针slow&#xff0c;fast一次移动两个节点&#xff0c;slow一次移动一个节点。&#xff08;前面…

决策管理中的数学方法

需要注意的是,用excel求解的时候需要导入线性规划加载项如下: pert分析需要DecisionTools中的RiskSolver插件 1.链接:https://pan.baidu.com/s/1wKhUFWgNmQ7U33kl5AypZw 提取码:zqkn 2.“Palisade_Book_expires_Aril_10_2025.lic”文件复制到以下路径: C:\Program Files …

Spring MVC(建立连接 + 请求)

文章目录 一、建立客户端和服务器的连接二、如何构造请求&#xff08;传参&#xff09;2.1 构造请求方式 参数通用注解2.2 传递单个参数2.3 传递多个参数2.4 传递数组/集合2.5 传递对象2.6 传递JSON 三、相关的其他请求操作3.1 获取URL中的参数 PathVariable3.2 上传文件 Requ…

ipa 分区算法分析,图解

参考 Room Segmentation: Survey, Implementation, and Analysis. 分区算法调查&#xff0c;实现以及评估对比 相关论文 分区算法 New Brooms Sweep Clean - An Autonomous Robotic Cleaning Assistant for Professional Office Cleaning 形态分割 Interactive SLAM using …

uniapp 小程序图片懒加载组件 ImageLazyLoad

预览图 组件【ImageLazyLoad】代码 <template><viewclass"image-lazy-load":style"{opacity: opacity,borderRadius: borderRadius rpx,background: background,transition: opacity ${time / 1000}s ease-in-out,}":class"image-lazy-loa…

1.分布式-理论

目录 一、什么是分布式系统 二、CAP理论 1.一致性Consisency 2.可用性(Availability) 3.分区容错性(Partition tolrance) 三、BASE理论 1.Basically Available(基本可用) 2.Soft state&#xff08;软状态&#xff09; 3.Eventually consistent&#xff08;最终一致性&a…

当代 Qt 正确的 安装方法 及 多版本切换

此文写于 20240511 首先去网站Index of /official_releases/online_installers下载一个安装器 安装器有什么用? 可以浏览安装版本 安装组件 安装器版本越能 能装的东西越多 现在只能选Qt5 和 Qt6 至于你公司用的Qt4 我也没招 见招时再拆招 安装器 默认国外源 可以换国内…

Bean的作用域和自动装配

Spring Bean的作用域主要有五种Singleton是单例类型,就是在创建起容器时就同时自动创建了一个bean的对象,不管你是否使用,他都存在了,每次获取到的对象都是同一个对象。注意,singleton作用域是Spring中的缺省作用域(默认的作用域)。 prototype是原型类型,它在我们创建容…

从0开始学python(七)

目录 前言 1 break、continue和pass函数 1.1 break 1.2 continue 1.3 pass 2、序列的索引及切片操作 2.1字符串的索引和切片 2.1.1 字符串索引 2.1.2 字符串切片 总结 前言 上一篇文章我们介绍了python中的循环结构&#xff0c;包括for和while的使用。本章接着往下讲。…

Chatgpt的应用场景

文案创作类&#xff1a; 作为一名大型语言模型&#xff0c;ChatGPT可以为使用者提供多种文本处理和文字创作方面的服务&#xff0c;例如&#xff1a; 文本生成和创作 ChatGPT可以基于您提供的主题、关键词或文本段落&#xff0c;生成符合使用者要求的新文本。这些文本可以是文…

跟着ChatGPT学算法-完全背包问题

一、题目 给定 n 个物品,第 i 个物品的重量为 wgt[i-1]、价值为 val[i-1] ,和一个容量为 cap 的背包。每个物品可以重复选取,问在限定背包容量下能放入物品的最大价值。二、和ChatGPT聊聊您 您是一位资深算法工程师,请深入浅出地给出完全背包问题的分析过程和完整带注释的J…

类型注解-Python

师从黑马程序员 类型注解的语法 类型注释的限制 import json import randomvar_1 : int10 var_2 : str"itheima" var_3 : boolTrueclass Student:pass stu :StudentStudent()my_list:list [1,2,3] my_tuple:tuple(1,2,3) my_dict:dict{"itheima":666}my_l…

MySQL5.7安装详细过程--window系统

一:MySQL5.7安装详细过程--window系统1.1、下载MySQL5.7安装包https://downloads.mysql.com/archives/community/1.2、将文件解压到盘符中你可以解压到你想解压的位置,放在C或其他盘符都可以。1.3、配置MySQL的环境变量由于我们下载的不是exe或者msi版本,不能直接双击安装,…

一文学会 Kubernetes Pod 的生命周期管理(转载)

收获 了解 Pod 的状态(Status) 了解 pod 阶段(Phase) 了解 Pod conditions了解容器状态(Status) 保持容器健康了解容器自动重启使用探活(liveness)探针(Probe)检查容器的健康状况如果程序启动缓慢,请使用 startup probeLiveness probe 一些建议 在容器启动和关闭时执…