数据结构算法题:栈与队列的使用(一)

目录

  • 用队列实现栈
    • 题目
    • 解题思路
    • 代码实现
      • 创建栈的结构体
      • 栈的初始化
      • 入栈
      • 出栈
      • 获取栈顶数据
      • 判断栈是否为空
      • 销毁栈

用队列实现栈

题目

题目描述:
在这里插入图片描述
示例:
在这里插入图片描述

解题思路

题目要求使用两个队列实现栈的入栈、出栈、获取栈顶元素、检查栈是否为空栈的基本操作。
既然要用到队列,我们首先得有能够实现队列基本操作的代码,这里直接复制之前已经写好的队列代码。

typedef int QDataType;
typedef struct QueueNode
{QDataType data;struct QueueNode* next;}QueueNode;typedef struct Queue
{QueueNode* phead;QueueNode* ptail;int size;
}Queue;
void QueueInit(Queue* pq)
{assert(pq);pq->phead = pq->ptail = NULL;pq->size = 0;
}
// ⼊队列,队尾
void QueuePush(Queue* pq, QDataType x)
{assert(pq);//申请新节点QueueNode* newnode =(QueueNode*)malloc(sizeof(QueueNode));if (newnode == NULL){perror("malloc fail!");exit(1);}newnode->data = x;newnode->next = NULL;//ptail newnodeif (pq->phead == NULL){//队列为空pq->phead = pq->ptail = newnode;}else{//队列不为空pq->ptail->next = newnode;pq->ptail = pq->ptail->next;//newnode}pq->size++;
}//队列判空
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->phead == NULL && pq->ptail == NULL;
}// 出队列,队头
void QueuePop(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));//只有一个结点的情况,避免ptail变成野指针if (pq->ptail == pq->phead){free(pq->phead);pq->phead = pq->ptail = NULL;}else{//删除队头元素、QueueNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}--pq->size;
}
//取队头数据
QDataType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->phead->data;
}//取队尾数据
QDataType QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->ptail->data;
}
//队列有效元素个数
int QueueSize(Queue* pq)
{assert(pq);/*int size = 0;QueueNode* pcur = pq->phead;while (pcur){size++ ;pcur = pcur->next;}return size;*/return pq->size;
}//销毁队列
void QueueDestroy(Queue* pq)
{assert(pq);//assert(!QueueEmpty(pq));QueueNode* pcur = pq->phead;while (pcur){QueueNode* next = pcur->next;free(pcur);pcur = next;}pq->phead = pq->ptail = NULL;pq->size = 0;
}

现在有了队列的代码,继续分析如何通过队列实现栈的操作。
队列是先进先出,栈的话是先进后出。
他说要使用两个队列,我们就先创建两个队列:
在这里插入图片描述
这两个队列就是我们的栈,当我们入栈时,就是将数据放入队列内。
第一种情况:这里假设栈里面没有数据,我们放入哪个队列都可以。
第二种情况:这里假设栈里面有数据,我们就需要放入不为空的队列内。
在这里插入图片描述
如上面这种情况,我们就需要放入Q1内,这样当我们取栈顶数据时,才可以正确出栈。
综合一下就是入栈的数据放入不为空的队列内。

出栈的操作:假设我们入栈放入的是Q1
在这里插入图片描述
根据栈先进后出的特性,我们取栈顶取的是3,有什么方法可以取出来?
显然我们可以将Q1内的数据出队列存入到Q2,但是不是全部转移,在队列结构体里面我们定义了有效数据个数size,我们只要转移size-1个数据,剩下的就是栈顶的数据。

根据上面这个例子,我们转移2个数据,当转移完后,我们就剩下了3,而3刚好就是我们需要的数据,在出栈后我们释放栈顶及释放队列头节点空间即可。
在这里插入图片描述

入栈出栈了解完了,再了解一下取栈顶数据。
数据是放在队列里面的,队列是有头指针phead和尾指针ptail的,我们找到不为空的队列,直接返回队列的尾节点数据即可。

这里注意我们的队列无论在什么时候,两个队列是肯定有一个为空的。
在这些操作例,能改变队列是否为空的操作就只有入栈跟出栈,但是入栈时我们放的是不为空的队列,出栈我们在取出数据后会删除栈顶的数据,这样无论如何我们都会保持一个队列为空队列。

因为不能通过视频的方式讲解,会显得比较凌乱,可以在之上通过画图来帮助自己理解。

代码实现

这里队列的操作函数在上面已经提供了,这些代码在前面讲解队列时全部讲解过了,有不了解的可以去回顾一下哈。

创建栈的结构体

typedef struct {Queue q1;//队列1Queue q2;//队列2
} MyStack;

栈的初始化

栈是由两个队列实现的,那初始化就是初始化两个队列。

MyStack* myStackCreate() {MyStack* ps=(MyStack*)malloc(sizeof(MyStack));QueueInit(&ps->q1);QueueInit(&ps->q2);return ps;
}

入栈

void myStackPush(MyStack* obj, int x) {if(!QueueEmpty(&obj->q1))//判断是否为空队列{QueuePush(&obj->q1,x);}else{QueuePush(&obj->q2,x);}
}

出栈

int myStackPop(MyStack* obj) {//定义两个变量分别指向空队列和不为空队列Queue* empq=&obj->q1;Queue* noneq=&obj->q2;if(!QueueEmpty(&obj->q1))//这里判断Q1是否为空,不为空就要替换一下{empq=&obj->q2;noneq=&obj->q1;}while(QueueSize(noneq)>1)//转移数据到空队列{int pop=QueueFront(noneq);QueuePush(empq,pop);QueuePop(noneq);}//出队列int pop =QueueFront(noneq);QueuePop(noneq);return pop;
}

获取栈顶数据

int myStackTop(MyStack* obj) {if(!QueueEmpty(&obj->q1))//寻找不为空的队列{return QueueBack(&obj->q1);}else{return QueueBack(&obj->q2);}
}

判断栈是否为空

就是判断两个队列是否为空队列,当有一个不满足就代表栈内部有数据。

bool myStackEmpty(MyStack* obj) {return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);
}

销毁栈

销毁两个队列

void myStackFree(MyStack* obj) {QueueDestroy(&obj->q1);//销毁队列1QueueDestroy(&obj->q2);//销毁队列2free(obj);obj=NULL;
}

感谢观看,有错请在评论区指正,谢谢。
最后赏赐小编一个三连吧各位看官老爷们。

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

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

相关文章

答题pk小程序的技术特点和性能优势分析

答题小程序是一种在移动设备上运行的应用程序,旨在提供各种类型的答题体验。以下是答题小程序的一些特点和优势: 一、特点 多样化的题目类型: 包括选择题、填空题、判断题等常见题型,还可能有简答题、论述题等更具挑战性的题型。…

健康推荐系统:SpringBoot技术实现

3系统分析 3.1可行性分析 通过对本基于智能推荐的卫生健康系统实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本基于智能推荐的卫生健康系统采用SSM框架&#…

Spire.PDF for .NET【页面设置】演示:在 C#/VB.NET 中创建 PDF 小册子

当人们打印大型 PDF 文档时,PDF 小册子非常有用。它在书籍、报纸和杂志编辑中特别受欢迎。本节将介绍一种通过C#、VB.NET 中的.NET PDF组件创建 PDF 小册子的非常简单的方法。 Spire.PDF for .NET 是一款独立 PDF 控件,用于 .NET 程序中创建、编辑和操作…

[含文档+PPT+源码等]精品基于django实现的原生Andriod天气信息的着装搭配系统

基于Django实现的原生Android天气信息的着装搭配系统背景,可以从以下几个方面进行详细阐述: 一、技术背景 Django框架: Django是一个高级的Python Web框架,它鼓励快速开发和干净、实用的设计。Django框架具有强大的数据库抽象层、…

深入了解EasyNVR及EasyNVS,EasyNVR连接到EasyNVS当显示授权超时如何解决?又因为什么原因?

我们先来了解NVR批量管理软件/平台EasyNVR,它深耕市场多年,为用户提供多种协议,兼容多种厂商设备,包括但不限于支持海康,大华,宇视,萤石,天地伟业,华为设备。 NVR录像机…

14.JVM对象创建与内存分配机制深度剖析

一、对象的创建 1.类加载检查 当虚拟机接受到一条new指令时,会去检查这个指令的参数是否能在常量池种定位到一个符号引用,并且检查这个符号引用代表的类是否已经被加载、解析和初始化。如果没有则进行类的加载过程; 2.分配内存 在类加载检…

【Unity实战篇】 接入百度翻译,实现文本自动翻译功能

前言【Unity实战篇】 接入百度自动翻译,实现文本自动翻译功能一、获取百度翻译开发平台的APPID和密钥二、Unity中接入自动翻译功能三、Unity中实现自动翻译文本Text功能总结前言 日常在做项目的过程中,游戏本地化几乎已经成为必不可少的一步。本篇文章将演示怎样在Unity中接入…

数据质量差的代价是什么?

如今,许多数字企业都认为自己是数据驱动的。通过各种软件解决方案,数据无处不在,收集起来也非常方便,这使得企业能够被动地收集大量数据,并将其应用于决策制定。 然而,人们往往很容易在不考虑数据质量的情…

新手爬虫DAY1

这个错误信息表明在你的Python程序中,re.search() 函数没有找到预期的匹配项,因此返回了 None。当你尝试在 None 对象上调用 group(1) 方法时,Python 抛出了一个 AttributeError。 具体来说,错误发生在 pc.py 文件的第6行&#x…

【实战篇】用SkyWalking排查线上[xxl-job xxl-rpc remoting error]问题

一、组件简介和问题描述 SkyWalking 简介 Apache SkyWalking 是一个开源的 APM(应用性能管理)工具,专注于微服务、云原生和容器化环境。它提供了分布式追踪、性能监控和依赖分析等功能,帮助开发者快速定位和解决性能瓶颈和故障。…

excel筛选多个单元格内容

通常情况下,excel单元格筛选时,只筛选一个条件,如果要筛选多个条件,可以如下操作: 字符串中间用空格分隔就行。

IDEA中git如何快捷的使用Cherry-Pick功能

前言 我们在使用IDEA开发时,一般是使用GIT来管理我们的代码,有时候,我们需要在我们开发的主分支上合并其他分支的部分提交代码。注意,是部分,不是那个分支的全部提交,这时候,我们就需要使用Che…

使用OpenCV实现基于FisherFaces的人脸识别

引言 随着人工智能技术的发展,人脸识别已经成为日常生活中不可或缺的一部分。在众多的人脸识别算法中,FisherFaces 方法因其简单易用且具有良好的识别效果而备受青睐。本文将详细介绍如何使用Python和OpenCV库实现基于FisherFaces的人脸识别系统&#x…

【SpringBoot】13 XML格式的请求和响应

介绍 可扩展标记语言 (Extensible Markup Language, XML) ,标准通用标记语言的子集,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 XML是标准通用标记语言 可扩展性良好,内容与形式分离,遵循严格的语法…

OPC UA与PostgreSQL如何实现无缝连接?

随着工业4.0的推进,数据交换和集成在智能制造中扮演着越来越重要的角色。OPC UA能够实现设备与设备、设备与系统之间的高效数据交换。而PostgreSQL则是一种强大的开源关系型数据库管理系统,广泛应用于数据存储和管理。如何将OPC UA与PostgreSQL结合起来&…

【力扣刷题实战】合并两个有序链表

大家好,我是小卡皮巴拉 文章目录 目录 力扣题目:合并两个有序链表 题目描述 示例 1: 示例 2: 示例 3: 解题思路 问题理解 算法选择 具体思路 解题要点 完整代码(C语言) 兄弟们共勉…

Palo Alto Networks Expedition 未授权SQL注入漏洞复现(CVE-2024-9465)

0x01 产品介绍: Palo Alto Networks Expedition 是一款强大的工具,帮助用户有效地迁移和优化网络安全策略,提升安全管理的效率和效果。它的自动化功能、策略分析和可视化报告使其在网络安全领域中成为一个重要的解决方案。 0x02 漏洞描述&am…

图像处理(二)——MDPI特刊推荐

特刊征稿 01 期刊名称: Computer Vision and Image Processing, 2nd Edition 截止时间: 投稿截止日期:2024年12月31日 目标及范围: 感兴趣的主题包括但不限于: 用于图像分类和识别的深度学习 对象检测和跟…

Chromium HTML5 <svg>对应c++接口说明

一、SVG:可缩放矢量图形 开始学习 SVG 可缩放矢量图形(Scalable Vector Graphics,SVG)基于 XML 标记语言,用于描述二维的矢量图形。 作为一个基于文本的开放网络标准,SVG 能够优雅而简洁地渲染不同大小的…

c高级10月15日

1,思维导图