用栈模拟实现队列(c语言版)

news/2024/10/30 17:30:08/

在这里插入图片描述

前言

用"栈实现队列",力扣中一道oj题,可以帮助刚接触"栈"和"队列"的新手更好的理解栈和队列这两种结构.

题目来源于力扣:
题目链接:https://leetcode.cn/problems/implement-queue-using-stacks/
难度:简单

目录

  • 前言
  • 一、队列的各接口:
    • 1.1 类型的声明(MyQueue):
    • 1.2 初始化(myQueueCreate):
    • 1.3 入队列(myQueuePush)
    • 1.4 出队列(myQueuePop)
    • 1.5 队列的判空(myQueueEmpty)
    • 1.6 返回队首元素(myQueuePeek):
    • 1.7 队列的销毁(myQueueFree):
  • 二、总代码:

一、队列的各接口:

1.1 类型的声明(MyQueue):

//模拟队列类型的声明
typedef struct {ST stackpush;		//用于模拟队列的 入队操作ST stackpop;		//用于模拟队列的 出队操作
} MyQueue;

这里是借助两个栈用于模拟队列.
①:stackpush 模拟队列的入队
②:stackpop 模拟队列的出队

在这里插入图片描述

1.2 初始化(myQueueCreate):

该队列是由两个栈实现的,所以重点关注两个栈的初始化即可.

步骤:

  1. 申请两个栈大小的空间.
    申请失败时判断一下.
  2. 对队列中的两个栈,一次调用他们的初始化函数.(这个千万别漏掉了,牛牛漏掉之后找了好久的问题)
//队列的初始化
MyQueue* myQueueCreate() {//给队列开辟空间MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));if(obj==NULL){perror("obj malloc fail");}//一定要记得这里要初始化(别漏掉了哦)InitST(&obj->stackpush);InitST(&obj->stackpop);return obj;
}

1.3 入队列(myQueuePush)

对于入队列的模拟实现很简单,只需要将数据压入栈(模拟入队列:stackpush)即可.

void myQueuePush(MyQueue* obj, int x) {assert(obj);STPush(&obj->stackpush,x);
}

1.4 出队列(myQueuePop)

函数要求:
将队首元素出队,并且返回刚刚出队的队首元素.

模拟出队相对复杂一些.

  1. 初始状态下或者stackpop(模拟出队的栈)数据出队列到空时,里面是没有数据的,所以先判断stackpop是否有数据.
    有数据:则直接获取stackpop栈顶元素作为队首元素.
    无数据:将数据从模拟入队列栈全部倒过来.(倒数据)
  2. 获取stackpop栈顶元素作为队首元素,使用top变量记录下来.(因为后面要执行出栈操作).
  3. 出栈(模拟出队列),并返回top变量.
int myQueuePop(MyQueue* obj) {assert(obj);if(STEmpty(&obj->stackpop))//如果栈(stackpop模拟出队列的栈)为空,则向栈(stackpush模拟入队列的栈)要数据{//下面循环结束的条件是不为空while(!STEmpty(&obj->stackpush))//将数据从模拟入队列栈全部倒过来{//将栈(stackpush模拟入队)的栈顶元素依次压入栈(stackpop模拟出栈)STPush(&obj->stackpop,STTop(&obj->stackpush));STPop(&obj->stackpush);}}int top=STTop(&obj->stackpop);//记录用来模拟出队列的栈的栈顶元素;STPop(&obj->stackpop);return top;
}

1.5 队列的判空(myQueueEmpty)

当两个栈中都没有元素时,则队列为空.

//写法1

bool myQueueEmpty(MyQueue* obj) {if(STEmpty(&obj->stackpush)&&STEmpty(&obj->stackpop))//如果都为空,则为空栈{return true;}else return false;
}

//写法2.

bool myQueueEmpty(MyQueue* obj) {return STEmpty(&obj->stackpush)	&&	STEmpty(&obj->stackpop);
}

1.6 返回队首元素(myQueuePeek):

  1. stackpop不为空时,则队首元素就是stackpop的栈元素.
  2. stackpop为空时,则队首元素就是stackpush的栈元素.
    所以这里也需要倒数据.
int myQueuePeek(MyQueue* obj) {assert(obj);if(STEmpty(&obj->stackpop))//如果栈(stackpop模拟出队列)为空,则向栈(stackpush模拟入队列)要数据{while(!STEmpty(&obj->stackpush)){//将栈(stackpush模拟入队)的栈顶元素依次压入栈(stackpop模拟出队列)STPush(&obj->stackpop,STTop(&obj->stackpush));STPop(&obj->stackpush);}}int top=STTop(&obj->stackpop);//记录用来模拟出队列的栈的栈顶元素;return top;
}

myQueuePop(出队列)函数比较,此函数只是将队首元素返回,并没有指向pop出队操作.
所以我们在实现myQueuePop函数时可以复用一下myQueuePeek函数.

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

1.7 队列的销毁(myQueueFree):

  1. 释放两个栈初始化开辟的空间
  2. 释放队列申请的空间.
void myQueueFree(MyQueue* obj) {STDestory(&obj->stackpush);STDestory(&obj->stackpop);free(obj);
}

二、总代码:

前面的代码是栈的实现,由于c语言不能像c++那样直接调用库.

typedef  int stacktype;typedef struct stack//定义栈的类型
{stacktype* data;int top;int capacaity;
}ST;
void InitST(ST* ps);//初始化栈
void STPush(ST* ps, stacktype x);//压栈
void STPop(ST* ps);//出栈
bool STEmpty(ST* ps);//判断是否为空栈
stacktype STTop(ST* ps);//返回栈顶元素
void STDestory(ST* ps);//栈的销毁void InitST(ST* ps)//初始化栈
{assert(ps);ps->top = -1;ps->capacaity = 4;ps->data = (stacktype*)malloc(ps->capacaity * sizeof(stacktype));}void STPush(ST* ps, stacktype x)//压栈
{assert(ps);if (ps->top+1 == ps->capacaity){ps->capacaity *= 2;ST* tmp = (stacktype*)realloc(ps->data, ps->capacaity * sizeof(stacktype));if(tmp == NULL){printf("增容失败\n");}ps->data = tmp;}ps->top++;ps->data[ps->top] = x;}void STPop(ST* ps)//出栈
{assert(ps);assert(!STEmpty(ps));ps->top--;
}bool STEmpty(ST* ps)//判断是否为空栈,是空返回真
{assert(ps);if (ps->top == -1){return true;}return false;
}
stacktype STTop(ST* ps)//返回栈顶元素
{assert(ps);return ps->data[ps->top];
}
void STDestory(ST* ps)//销毁栈
{assert(ps);free(ps->data);ps->data = NULL;ps->top = -1;ps->capacaity = 0;
}//模拟队列类型的声明
typedef struct {ST stackpush;ST stackpop;
} MyQueue;//队列的初始化
MyQueue* myQueueCreate() {MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));if(obj==NULL){perror("obj malloc fail");}//一定要记得这里要初始化InitST(&obj->stackpush);InitST(&obj->stackpop);return obj;
}void myQueuePush(MyQueue* obj, int x) {assert(obj);STPush(&obj->stackpush,x);
}int myQueuePop(MyQueue* obj) {assert(obj);if(STEmpty(&obj->stackpop))//如果栈(stackpop模拟出栈)为空,则向栈(stackpush模拟入栈)要数据{while(!STEmpty(&obj->stackpush)){//将栈(stackpush模拟入队)的栈顶元素依次压入栈(stackpop模拟出栈)STPush(&obj->stackpop,STTop(&obj->stackpush));STPop(&obj->stackpush);}}int top=STTop(&obj->stackpop);//记录用来模拟出队列的栈的栈顶元素;STPop(&obj->stackpop);return top;
}bool myQueueEmpty(MyQueue* obj) {if(STEmpty(&obj->stackpush)&&STEmpty(&obj->stackpop))//如果都为空,则为空栈{return true;}else return false;//return STEmpty(&obj->stackpush)&&STEmpty(&obj->stackpop);
}int myQueuePeek(MyQueue* obj) {if(STEmpty(&obj->stackpop))//如果栈(stackpop模拟出栈)为空,则向栈(stackpush模拟入栈)要数据{while(!STEmpty(&obj->stackpush)){//将栈(stackpush模拟入队)的栈顶元素依次压入栈(stackpop模拟出栈)STPush(&obj->stackpop,STTop(&obj->stackpush));STPop(&obj->stackpush);}}int top=STTop(&obj->stackpop);//记录用来模拟出队列的栈的栈顶元素;return top;//return STTop(&obj->stackpop);
}void myQueueFree(MyQueue* obj) {STDestory(&obj->stackpush);STDestory(&obj->stackpop);free(obj);
}

运行结果:
在这里插入图片描述


http://www.ppmy.cn/news/307889.html

相关文章

海康威视6300D系列解码器(6308D)部分通道不能解码的故障

公司部署了大量的海康威视IPC,但在控制台上,遇有部分通道无法解码的情况。 但使用6400HD-S系列高清屏幕拼接控制器,就可以正常解码。 咨询海康威视客服,让我升级摄象机的固件,但并未凑效。 后经过反复对比排查&#…

C++ std::thread 与Qt qthread多线程混合编程

C与Qt深度融合:高效设计多线程应用框架 1. C与Qt线程的混合使用1.1 C线程与Qt线程的基本概念1.2 线程间的相互依赖关系1.3 设计合理的代码框架 二、深入理解C和Qt线程模型2.1 C线程模型2.2 Qt线程模型2.3 C和Qt线程模型的比较 三、C和Qt线程间的互操作性3.1 std::th…

mac性能比服务器好,2020款MacbookAir和MacbookPro13区别是什么 性能参数对比介绍

2020款的Macbook Air和Macbook Pro13英寸两款笔记本都已经正式推出,这两款笔记本电脑在性能参数上有哪些不同,这里我们主要对比同样采用M1芯片的两款笔记本作为对比。 1、MabookAir可以使用触控ID解锁,但没有触控栏功能,MabookPro…

macbook air恢复出厂设置

macbook air恢复出厂设置的方法为: 1、重启macbook air,当系统重启时,同时按“commandR”键进入恢复模式; 2、在macos的实用窗口里,选择“磁盘工具”,再选择“继续”; 3、点击主硬盘&#xf…

Macbook Air(13-inch, Early 2015) 重新安装操作系统

1. 系统信息如下 上次安装 操作系统的时候,硬盘格式化成区分大小写了。导致 Adobe illustrator 安装不上去。这里重新安装一下操作系统。 2. 格式化磁盘为不区分大小写的格式 Intel 处理器 将 Mac 开机并立即按住 Command (⌘)-R,直至你看到 Apple 标志…

2019pro与air怎么选_2020款MacBookAir高配和2019款MacbookPro13丐版买哪个?

2020款MacBook Air 高配 和2019款Macbook Pro 13丐版买哪个?我相信有非常多的朋友都有这个疑问。 我正有打算写一篇这个对比的文章。看到已经有了这个问题,就先来简单回答一下。稍后会在个人主页做整体的分析文章。 首先我们先来确认一下2020款MacBook air 高配和2…

macbookair有没有touchbar_macbookair2016和2017款有什么区别 macbookair2016和2017款对比解析...

类型:Mac办公软件大小:20M语言:中文 评分:10.0 标签: 立即下载 macbookair2016和2017款有什么区别?macbookair2016和2017款对比解析。最近有伙伴准备入手macbookair但是不知道买2016款还是2017款&#xff0…

MacBook Air 2013年中10.9版本升级到macOS Sierra

1、有条件的情况下,先备份系统,具体备份操作参考https://support.apple.com/zh-cn/HT201250,若出现问题可给我留言 2、我是更新到macOS Sierra,所以先看看自己的设备是否符合要求 2009 年末推出的 [MacBook](https://support.appl…