用栈实现队列(C语言)

目录

  • 题目
    • 题目分析
  • 代码
    • 栈的实现
      • 结构体。
      • 栈的初始化
      • 栈的销毁
    • 入栈
      • 删除
      • 查找顶部数据
      • 判空
    • 答案
      • 结构体
      • 初始化
      • 插入数据
      • 删除数据
      • 获取队列开头元素
      • 判空
      • 销毁栈

题目

题目分析

链接: 题目

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类:

void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false

根据题目,我们可以知道,我们需要用两个栈来实现队列,的出入规则是后进先出,而队列的出入规则是先进先出
如果我们现在又两个栈,pushpstpopst,先在pushst中入4个数据(4,3,2,1)。
在这里插入图片描述
如果我们要出数据的话,我们根据队列的出入原则,应该出数据1,所以我们可以把pushst里面的数据全部倒入到popst中,那么popst中的数据为(1,2,3,4).
如图:
在这里插入图片描述
如果需要出数据的话,直接按照顺序出就可以了。
那么,问题来了,我们要入数据,需要在哪个栈里面入?
答案是pushst.如果我们要入数据(5,6).
在这里插入图片描述
pushst拿来入数据,popst拿来出数据,刚好可以满足队列的需求。先出四个数据。
在这里插入图片描述
想再出数据时,已经没有数据了,我们需要从pushst里再次倒入数据(5,6),
在这里插入图片描述
再依此类推…

代码

栈的实现

我们实现栈使用的是数组。

结构体。

先创建一个结构体

typedef int STDataType;
typedef struct stack
{STDataType* a;int top;//栈当前大小int capacity;//栈的大小
}ST;

栈的初始化

void STInit(ST* pst)
{assert(pst);pst->a = NULL;pst->capacity = 0;pst->top = 0;
}

栈的销毁

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

入栈

void Push(ST* pst, STDataType x)
{assert(pst);if (pst->top == pst->capacity)//如果栈的空间不够了,我们需要扩容。{int newnode = pst->capacity == 0 ? 4 : pst->capacity * 2;STDataType* tmp = (STDataType*)realloc(pst->a, sizeof(STDataType) * newnode);if (tmp == NULL) {perror("realloc:fail");}pst->a = tmp;pst->capacity = newnode;}pst->a[pst->top++] = x;
}

删除

void Pop(ST* pst)
{assert(pst);assert(pst->top > 0);pst->top--;//只需要顶部删除即可
}

查找顶部数据

STDataType Top(ST* pst)
{return pst->a[pst->top-1];
}

判空

bool STEmpty(ST* pst)
{assert(pst);return pst->top == 0;
}

答案

我们需要先创建两个栈的结构体

结构体

typedef struct {ST pushst;ST popst;
} MyQueue;

初始化

MyQueue* myQueueCreate() {MyQueue * obj = (MyQueue*)malloc(sizeof(MyQueue));STInit(&obj->pushst);//对每一个队列进行初始化STInit(&obj->popst);return obj;
}

插入数据

void myQueuePush(MyQueue* obj, int x) {Push(&obj->pushst,x);//只需要往pushst里面插入就可以了
}

删除数据

先对popst判空,如果为空,我们需要倒入数据后,再删除数据。

int myQueuePop(MyQueue* obj) {if(STEmpty(&obj->popst)){while(!STEmpty(&obj->pushst)){Push(&obj->popst,Top(&obj->pushst));Pop(&obj->pushst);//倒入一个,记得删除一个}}int top = Top(&obj->popst);//获取顶部苏数据Pop(&obj->popst);//删除顶部数据return top;
}

获取队列开头元素

跟myQueuePop(MyQueue* obj)函数类似

int myQueuePeek(MyQueue* obj) {if(STEmpty(&obj->popst)){while(!STEmpty(&obj->pushst)){Push(&obj->popst,Top(&obj->pushst));Pop(&obj->pushst);}}return Top(&obj->popst);
}

判空

两个栈为空,队列才为空。

bool myQueueEmpty(MyQueue* obj) {return STEmpty(&obj->popst) && STEmpty(&obj->pushst);
}

销毁栈

先要对连个队列进行销毁,再对两个栈的结构体销毁。

void myQueueFree(MyQueue* obj) {STDestory(&obj->popst);STDestory(&obj->pushst);free(obj);
}

在这里插入图片描述

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

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

相关文章

pyside6下没有designer.exe、pyside6-uic.exe等

使用conda安装的pyside6(conda install pyside6),发现pyside6目录下没有designer.exe、pyside6-uic.exe等;designer.exe在Miniconda3/Library/bin下 pyside6-uic.exe、pyside6-rcc.exe在Miniconda3\Scripts下 但是 使用pip安装…

【MyBatis】MyBatis解析全局配置文件源码详解

目录 一、前言 思维导图概括 二、配置文件解析过程分析 2.1 配置文件解析入口 2.2 初始化XMLConfigBuilder 2.3 XMLConfigBuilder#parse()方法:解析全局配置文件 2.3.1 解析properties配置 2.3.2 解析settings配置 2.3.2.1 元信息对象(MetaClas…

解决移植Metasploitable3到VM虚拟机无网络的问题

第一步 导入后不要开机,先在虚拟机设置里面将原有的两个网络适配器移除。 第二步 接着在选项里面,在客户机操作系统里面,选择Microsoft Windwos(W), 版本选择Windows Server 2008 R2 x64 第三步 先打开虚拟机,然后…

Python_文件操作_学习

目录 一、关于文件的打开和关闭 1. 文件的打开 2.文件的关闭 二、文件的读取 1. 文件的读_r 2. 使用readline 3.使用readlines 三、文件的写入 1. 文本的新建写入 2.文本的追加写入 四、文件的删除和重命名 1.文件的重命名 2.文件的删除 五、文件的定位读写 1.t…

Unity Miscellaneous入门

概述 在Unity中有非常多好用的组件,也是Unity为我们提供的方便的开发工具,它的功能可能不是主流的内容,比如渲染,音乐,视频等等,所有Unity把这些内容统一归到了一个杂项文件组中。 Unity组件入门篇总目录-…

Python线程

Python线程 1. 进程和线程 先来了解下进程和线程。 类比: 一个工厂,至少有一个车间,一个车间中至少有一个工人,最终是工人在工作。 一个程序,至少有一个进程,一个进程中至少有一个线程,最终…

langchain实战-从0到1搭建ai聊天机器人

介绍 当前,人工智能大模型公司如雨后春笋般迅速涌现,例如 OpenAI、文心一言、通义千问等,它们提供了成熟的 API 调用服务。然而,随之而来的是不同公司的繁琐协议接入过程,这让许多开发者感到头疼不已。有没有一种统一…

SpringBoot + Redis实现对接口的限流

目录 前言 什么是限流? 实现限流 创建一个注解类 接着创建一个切面类 前言 在项目中,对于接口的限流,是任何项目都必不可少的一部分,主要是为了防止用户频繁的发送请求,对服务器造成压力。 另外一点就是防止外来攻…

C++之第八课

课程列表 今天我们来学一学C里的一些实用的东西。 1.域宽 说到域宽setw&#xff0c;就叒要加头文件了。 #include<iomanip> 使用格式是&#xff1a; cout<<setw(5)<<"123"; setw括号里面可以改数字&#xff0c;后面就是输出内容了&#xff…

COD论文笔记 Boundary-Guided Camouflaged Object Detection

动机 挑战性任务&#xff1a;伪装物体检测&#xff08;COD&#xff09;是一个重要且具有挑战性的任务&#xff0c;因为伪装物体往往与背景高度相似&#xff0c;使得准确识别和分割非常困难。现有方法的不足&#xff1a;现有的深度学习方法难以有效识别伪装物体的结构和细节&am…

MySQL索引、视图练习

素材 1.学生表&#xff1a;Student (Sno, Sname, Ssex , Sage, Sdept) 学号&#xff0c;姓名&#xff0c;性别&#xff0c;年龄&#xff0c;所在系 Sno为主键 2.课程表&#xff1a;Course (Cno, Cname,) 课程号&#xff0c;课程名 Cno为主键 3.学生选课表&#xff1a;SC (Sno…

Home Credit - Credit Risk Model Stability

本篇是对Kaggle上Home Credit - Credit Risk Model Stability竞赛中的开源代码VotingClassifier Home Credit的解读。原链接在VotingClassifier Home Credit (kaggle.com)。 %%writefile script.py import sys from pathlib import Path import subprocess import os import g…

浅谈JMeter运行原理

浅谈JMeter运行原理 JMeter架构基础 JMeter基于Java平台开发&#xff0c;运行于Java虚拟机&#xff08;JVM&#xff09;之上。这意味着它可以在任何支持JVM的操作系统上运行&#xff0c;包括Windows、Linux、macOS等。其核心架构设计围绕着多线程执行机制&#xff0c;这使得它…

AI大模型探索之路-实战篇6: Function Calling技术调研之详细流程剖析

系列篇章&#x1f4a5; AI大模型探索之路-实战篇4&#xff1a;DB-GPT数据应用开发框架调研实践 AI大模型探索之路-实战篇5&#xff1a; Open Interpreter开放代码解释器调研实践 目录 系列篇章&#x1f4a5;一、前言二、Function Calling详细流程剖析1、创建OpenAI客户端2、定…

PCL 法向量加权的RANSAC拟合分割平面

目录 一、算法原理1、原理概述2、主要函数二、代码实现三、结果展示四、相关链接本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法原理 1、原理概述

鸿蒙布局List简介

鸿蒙布局List简介 List--常见的布局容器List 创建方式创建方式一&#xff0c;通过Listitem创建方式二&#xff0c;通过ForEach和Listitem创建方式三&#xff0c;通过ListItemGroup List–常见的布局容器 List是在app开发中最常见的一种布局方式&#xff0c;例如通讯录、新闻列…

Wpf 使用 Prism 实战开发Day24

自定义询问窗口 当需要关闭系统或进行删除数据或进行其他操作的时候&#xff0c;需要询问用户是否要执行对应的操作。那么就需要一个弹窗来给用户进行提示。 一.添加自定义询问窗口视图 (MsgView.xaml) 1.首先&#xff0c;添加一个自定义询问窗口视图 (MsgView.xaml) <Use…

域内攻击 ----->约束非约束委派攻击

在域中&#xff0c;除了我们常见的横向移动以外&#xff0c;还有很多攻击&#xff0c;像什么kerberoasting&#xff0c;委派攻击&#xff0c;NTLMrelay啊...... 还有很多&#xff08;暂时只知道这些&#xff09; 以前在一篇公众号看到的一个笑话也荟萃了网安的一些攻击手法&am…