【栈和队列OJ题】

栈和队列OJ题

文章目录

  • 栈和队列OJ题
    • 1. 用队列实现栈
    • 2. 用栈实现队列
    • 3. 括号匹配问题
    • 4. 循环队列

1. 用队列实现栈

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

好的,我们一起来看一下题目,题目是这样说的

在这里插入图片描述

思路:使用两个队列,始终保持一个队列为空。当我们需要进行进栈操作时,将数据进入不为空的队列中(若两个都为空,则随便压入一个队列)。当需要进行出栈操作时,将不为空的队列中的数据导入空队列,仅留下一个数据,这时将这个数据返回并且删除即可。判断栈是否为空,即判断两个队列是否同时为空

举个例子,我们将 1,2,3,4 进栈,实际上就是进入其中一个队列 q1

在这里插入图片描述

如果我们要出栈是不是就是按照 4,3,2,1 的顺序,我们将 1,2,3 push 到第二个队列 q2 中,然后在 q1pop 4 就完成出栈的一步操作

在这里插入图片描述

然后我们就可以 push q2 中的 1,2q1 ,这样就可以留一个 3q2 然后 pop q2 就可以完成 3 的出栈操作

在这里插入图片描述

以此循环就可以完成出栈的全部操作

在这里插入图片描述

下面就是代码实现:

typedef int QDataType;
typedef struct QueueNode
{struct QueueNode* next;QDataType data;
}QNode;typedef struct Queue
{QNode* head;QNode* tail;int size;
}Queue;void QueueInit(Queue* pq);
void QueueDestory(Queue* pq);
void QueuePush(Queue* pq, QDataType x);
void QueuePop(Queue* pq);QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);bool QueueEmpty(Queue* pq);
int QueueSize(Queue* pq);void QueueInit(Queue* pq)
{assert(pq);pq->size = 0;pq->head = pq->tail = NULL;
}void QueueDestory(Queue* pq)
{assert(pq);QNode* cur = pq->head;while (cur){QNode* del = cur;cur = cur->next;free(del);}pq->size = 0;pq->head = pq->tail = NULL;
}void QueuePush(Queue* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail\n");exit(-1);}else{newnode->data = x;newnode->next = NULL;}if (pq->tail == NULL){pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}pq->size++;
}bool QueueEmpty(Queue* pq)
{return pq->tail == NULL && pq->head == NULL;
}void QueuePop(Queue* pq)
{assert(pq);assert(!(QueueEmpty(pq)));if (pq->head->next == NULL){free(pq->head);pq->head = pq->tail = NULL;}else{QNode* del = pq->head;pq->head = pq->head->next;free(del);del = NULL;}pq->size--;
}QDataType QueueFront(Queue* pq)
{assert(pq);assert(!(QueueEmpty(pq)));return pq->head->data;
}QDataType QueueBack(Queue* pq)
{assert(pq);assert(!(QueueEmpty(pq)));return pq->tail->data;
}int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}typedef struct {Queue q1;Queue q2;
} MyStack;MyStack* myStackCreate() {MyStack* obj = (MyStack*)malloc(sizeof(MyStack));QueueInit(&obj->q1);QueueInit(&obj->q2);return obj;}void myStackPush(MyStack* obj, int x) {if (!QueueEmpty(&obj->q1)){QueuePush(&obj->q1, x);}else{QueuePush(&obj->q2, x);}}int myStackPop(MyStack* obj) {Queue* empty = &obj->q1;Queue* noEmpty = &obj->q2;if (!QueueEmpty(&obj->q1)){empty = &obj->q2;noEmpty = &obj->q1;}while (QueueSize(noEmpty) > 1){QueuePush(empty, QueueFront(noEmpty));QueuePop(noEmpty);}int top = QueueFront(noEmpty);QueuePop(noEmpty);return top;
}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) {QueueDestory(&obj->q1);QueueDestory(&obj->q2);free(obj);
}

2. 用栈实现队列

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

好的,我们一起来看一下题目,题目是这样说的

在这里插入图片描述

思路:使用两个栈,第一个栈只用于数据的输入,第二个栈只用于数据的输出。当需要输出数据,但第二个栈为空时,先将第一个栈中的数据一个一个导入到第二个栈,然后第二个栈再输出数据即可

举个例子 ,我想要按照 1,2,3,4 的顺序入队列,那就是要按照 1,2,3,4 的顺序出队列,我们可以先入一个栈,然后将第一个栈中的数据一个一个导入到第二个栈,输入即可

在这里插入图片描述

下面就是代码实现:

typedef int STDataType;
typedef struct Stack
{STDataType* _a;int _top; // 栈顶int _capacity; // 容量
}Stack;// 初始化栈
void StackInit(Stack* ps);// 入栈
void StackPush(Stack* ps, STDataType data);// 出栈
void StackPop(Stack* ps);// 获取栈顶元素
STDataType StackTop(Stack* ps);// 获取栈中有效元素个数
int StackSize(Stack* ps);// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
bool StackEmpty(Stack* ps);// 销毁栈
void StackDestroy(Stack* ps);bool StackEmpty(Stack* ps)
{assert(ps);return ps->_top == 0;
}int StackSize(Stack* ps)
{assert(ps);return ps->_top;
}STDataType StackTop(Stack* ps)
{assert(ps);assert(!StackEmpty(ps));return ps->_a[ps->_top - 1];
}void StackInit(Stack* ps)
{assert(ps);ps->_a = NULL;ps->_capacity = ps->_top = 0;
}void StackPush(Stack* ps, STDataType data)
{assert(ps);if (ps->_top == ps->_capacity){int newCapacity = ps->_capacity == 0 ? 4 : ps->_capacity * 2;STDataType* tmp = (STDataType*)realloc(ps->_a, newCapacity * sizeof(STDataType));if (NULL == tmp){perror("malloc fail");exit(-1);}ps->_a = tmp;ps->_capacity = newCapacity;}ps->_a[ps->_top] = data;ps->_top++;
}void StackPop(Stack* ps)
{assert(ps);ps->_top--;
}void StackDestroy(Stack* ps)
{assert(ps);free(ps->_a);ps->_a = NULL;ps->_capacity = ps->_top = 0;
}typedef struct {Stack pushST;Stack popST;
} MyQueue;MyQueue* myQueueCreate() {MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));StackInit(&obj->pushST);StackInit(&obj->popST);return obj;
}void myQueuePush(MyQueue* obj, int x) {StackPush(&obj->pushST, x);
}void PushSTToPopST(MyQueue* obj)
{if (StackEmpty(&obj->popST)){while (!StackEmpty(&obj->pushST)){StackPush(&obj->popST, StackTop(&obj->pushST));StackPop(&obj->pushST);}}
}int myQueuePop(MyQueue* obj) {PushSTToPopST(obj);int front = StackTop(&obj->popST);StackPop(&obj->popST);return front;
}int myQueuePeek(MyQueue* obj) {PushSTToPopST(obj);int front = StackTop(&obj->popST);return front;
}bool myQueueEmpty(MyQueue* obj) {return StackEmpty(&obj->popST) && StackEmpty(&obj->pushST);}void myQueueFree(MyQueue* obj) {StackDestroy(&obj->pushST);StackDestroy(&obj->popST);free(obj);
}

3. 括号匹配问题

OJ链接:20. 有效的括号 - 力扣(LeetCode)

好的,我们一起来看一下题目,题目是这样说的

在这里插入图片描述

思路:该题是栈的典型应用,满足后进先出的规则(后入栈的前括号将优先与先出现的后括号相匹配)。遍历字符串,遇到前括号直接入栈。遇到后括号,判断该后括号与栈顶的前括号是否匹配(若此时栈为空,则字符串无效),若不匹配则字符串无效;若匹配则删除栈顶元素,继续遍历字符串,直到字符串遍历完毕。当字符串遍历完后,检测栈是否为空,若为空,则字符串有效,若不为空,说明有前括号未匹配,字符串无效

typedef char STDataType;
typedef struct Stack
{STDataType* _a;int _top; // 栈顶int _capacity; // 容量
}Stack;// 初始化栈
void StackInit(Stack* ps);// 入栈
void StackPush(Stack* ps, STDataType data);// 出栈
void StackPop(Stack* ps);// 获取栈顶元素
STDataType StackTop(Stack* ps);// 获取栈中有效元素个数
int StackSize(Stack* ps);// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
bool StackEmpty(Stack* ps);// 销毁栈
void StackDestroy(Stack* ps);bool StackEmpty(Stack* ps)
{assert(ps);return ps->_top == 0;
}int StackSize(Stack* ps)
{assert(ps);return ps->_top;
}STDataType StackTop(Stack* ps)
{assert(ps);assert(!StackEmpty(ps));return ps->_a[ps->_top - 1];
}void StackInit(Stack* ps)
{assert(ps);ps->_a = NULL;ps->_capacity = ps->_top = 0;
}void StackPush(Stack* ps, STDataType data)
{assert(ps);if (ps->_top == ps->_capacity){int newCapacity = ps->_capacity == 0 ? 4 : ps->_capacity * 2;STDataType* tmp = (STDataType*)realloc(ps->_a, newCapacity * sizeof(STDataType));if (NULL == tmp){perror("malloc fail");exit(-1);}ps->_a = tmp;ps->_capacity = newCapacity;}ps->_a[ps->_top] = data;ps->_top++;
}void StackPop(Stack* ps)
{assert(ps);ps->_top--;
}void StackDestroy(Stack* ps)
{assert(ps);free(ps->_a);ps->_a = NULL;ps->_capacity = ps->_top = 0;
}bool isValid(char * s){Stack st;StackInit(&st);while(*s){if(*s == '(' || *s == '[' || *s == '{'){StackPush(&st, *s);}else{if(StackEmpty(&st)){StackDestroy(&st);return false;}else{if((*s == ')' && StackTop(&st) != '(')|| (*s == ']' && StackTop(&st) != '[')|| (*s == '}' && StackTop(&st) != '{')){StackDestroy(&st);return false;}StackPop(&st);}}++s;}if(!StackEmpty(&st)){StackDestroy(&st);return false;}return true;
}

4. 循环队列

OJ链接:622. 设计循环队列 - 力扣(LeetCode)

好的,我们一起来看一下题目,题目是这样说的

在这里插入图片描述

思路:在环形队列中,队列为空时,队头队尾指向同一个位置。当队列不为空时,队头指向插入的第一个数据,队尾指向最后一个数据的下一个位置。当tail+1等于front时,说明环形队列已满。
注意:环形队列的队尾不能像常规队列中队尾一样指向最后一个数据,如果这样的话,我们将不能区别环形队列的状态是空还是满,因为此时队头和队尾都指向同一个位置。这就意味着,我们必须留出一个空间,这个空间不能存放数据,这样我们才能很好的区别环形队列的状态是空还是满。
在这里插入图片描述

实现代码如下:

typedef struct {int* a;int head;int tail;int size;
} MyCircularQueue;bool myCircularQueueIsEmpty(MyCircularQueue* obj) {return obj->head == obj->tail;
}bool myCircularQueueIsFull(MyCircularQueue* obj) {return (obj->tail + 1) % obj->size == obj->head;
}MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));obj->a = (int*)malloc(sizeof(int) * (k+1));obj->head = obj->tail = 0;obj->size = k + 1;return obj;
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {if(myCircularQueueIsFull(obj)){return false;}else{obj->a[obj->tail] = value;obj->tail++;obj->tail %= obj->size;return true;}
}bool myCircularQueueDeQueue(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return false;}else{obj->head++;obj->head %= obj->size;return true;}
}int myCircularQueueFront(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return -1;}else{return obj->a[obj->head];}
}int myCircularQueueRear(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return -1;}else{return obj->a[(obj->tail - 1 + obj->size) % obj->size];}
}void myCircularQueueFree(MyCircularQueue* obj) {free(obj->a);free(obj);
}

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

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

相关文章

百日筑基第十七天-消息队列入门

百日筑基第十七天-消息队列入门 基础概念 什么是消息队列? MQ:Message Queue 存放消息的队列,消费消息时是按照顺序(队列先进先出)消费的。 参与消息传递的双方称为 生产者 和 消费者 ,生产者负责发送…

2024年06月CCF-GESP编程能力等级认证C++编程三级真题解析

本文收录于专栏《C等级认证CCF-GESP真题解析》,专栏总目录:点这里。订阅后可阅读专栏内所有文章。 一、单选题(每题 2 分,共 30 分) 第 1 题 小杨父母带他到某培训机构给他报名参加CCF组织的GESP认证考试的第1级&…

天润融通引领客服革新,AI大模型助力品牌服务升级

AI时代,消费零售品牌的客户服务应该怎么做? 如今消费者的关注点已经越来越复杂,一条毛巾,关注点就可以包括: 是否婴幼儿可用,是否儿童成人可用;是否可以直接接触皮肤;是否无甲醛、…

张量笔记(4):张量网络

张量分解通常是将高维张量分解成一系列较低维的张量,表示能力相对较低。而张量网络可以表示复杂的高维数据结构,通过连接多个张量形成网络结构,可以更灵活地表示和处理复杂的数据关系。本节主要介绍HT和TT网络。 2.5.1 HT分解——首先我们引入…

一篇文章解锁vue2

本文章对标vue2笔记内容,欢迎补充 文章目录 Vue介绍Vue2的生命周期生命周期钩子 使用vue/cli(脚手架)创建项目工程组件属性refpropsmixinplugins插件 数组更新检测(会改变原数组)添加/修改响应式布局vue内置指令自定义…

可道云teamOS,用个人标签和公共标签,文件分类更多样

在信息爆炸的时代,我们每天都在与海量的数据和信息打交道。如何在这些纷繁复杂的信息中快速找到我们需要的,成为了摆在我们面前的一大难题。 为大家介绍一下可道云teamOS个人标签和公共标签功能,让信息的整理与搜索变得简单高效。 一、个人…

WAN 和 LAN 分别是什么?

WAN(Wide Area Network,广域网)和LAN(Local Area Network,局域网)是两种不同类型的计算机网络,在覆盖范围、用途和技术实现上有所区别。 覆盖范围: LAN:通常覆盖一个较小…

怎么有效做性能测试?85%的测试不知道!

在质量角度而言,针对一个被测的对象,不仅仅需要考虑它功能层面的完整性,也需要非功能场景下系统的健壮性和稳定性。一个系统最核心的是它的稳定性、完整性、以及弹性的能力。能够在不可预知以及突发的情况下系统能够平稳有效的平滑过去&#…

Transformer的最新的研究论文与成果 - Transformer教程

近年来,Transformer模型在自然语言处理(NLP)领域取得了显著的进展。从其最初由Google提出的论文《Attention is All You Need》,到如今被广泛应用于各大NLP任务,Transformer无疑成为了机器学习中的明星架构。那么&…

微信小程序之使用上拉加载实现图片懒加载

在微信小程序中,有2个事件,相信大家都很熟悉 下拉重新加载 上拉加载更多 事件是这么个事件,至于事件触发后干嘛,那就看代码了 首先要在对应得地方xxxxpage.json打开这个 "onReachBottomDistance": 100至于这个值100还是…

小红薯做私域的9个重要步骤!

做私域如何找到安全、有效且高效的yin流方法!!应该是大家醉醉关心的问题了吧,有很多伙伴们要 么被jin言w规了,要么正在去往被xian流的路上… 1w个s域好友>10w粉丝的变现价值! 今天就一次性给大家总结了:…

pom.xml中重要标签介绍

在 Maven 项目中&#xff0c;pom.xml 文件是项目对象模型&#xff08;POM&#xff09;的配置文件&#xff0c;它定义了项目的依赖关系、插件、构建配置等。以下是 pom.xml 文件中一些重要的标签及其作用&#xff1a; <modelVersion>&#xff1a; 定义 POM 模型的版本。当…

MySQL 面试相关问题

写在前面&#xff1a; 不喜勿喷&#xff0c;暴躁作者又不求你给钱【没办法&#xff0c;遇见的狗喷子太多了&#x1f436;】欢迎大家在评论区留言&#xff0c;指正文章中的信息错误有一些其他相关的问题&#xff0c;可以直接评论区留言&#xff0c;作者看到会及时更新到文章末尾…

【thingsbord源码编译】 显示node内存不足

编译thingsbord显示报错 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory问题原因分析 重新安装java版本 编译通过

F1-score

F1-score F1-score 是一种衡量分类模型性能的指标&#xff0c;特别适用于处理极度不平衡的数据集&#xff0c;F1-score 的取值范围是从0到1&#xff0c;数值越大&#xff0c;表示性能越好。 计算公式&#xff1a; F1-score是精确率和召回率的调和平均数。 ∗ ∗ F 1 s c o r e…

数据分析的汇报与观点表达

什么是数据图表? 基于数据的规模,趋势,占比,关系等情况制作出来的图表。 什么是数据表达? 基于数据化的表、图、文说明事实表达观点。 目的 将业务细节转化成数据,借助数据来认知业务,数据表达就可以更好地说明现状,阐述事实,更多情况是论证观点。 为什么要基于数…

Ubuntu实战续篇:Apache httpd轻松搭建高效代理服务器

Ubuntu实战续篇&#xff1a;Apache httpd轻松搭建高效代理服务器 一、前言二、Ubuntu下的Apache配置文件概览三、配置并启用 Apache 代理服务 作者&#xff1a;高玉涵 时间&#xff1a;2024.7.11 21:06 博客&#xff1a;blog.csdn.net/cg_i 环境&#xff1a;Ubuntu 22.04.4 LTS…

基于React 实现井字棋

一、简介 这篇文章会基于React 实现井字棋小游戏功能。 二、效果演示 三、技术实现 import {useEffect, useState} from "react";export default (props) > {return <Board/> }const Board () > {let initialState [[, , ], [, , ], [, , ]];const [s…

yolov8、RTDETR无法使用多个GPU训练

yolov8、RTDETR无法使用多个GPU训练 网上看了好多解决方法&#xff1a; 什么命令行 CUDA_VISIBLE_DEVICES0,1 python train.py 环境变量都不行 最后找到解决方案&#xff1a;在ultralytics/engine/trainer.py 中的第246行 将 self.model DDP(self.model, device_ids[RANK])…

固体物理学习笔记(持续更新

目录 固体物理学&#xff08;黄昆&#xff09;晶格周期性的函数 固体物理学&#xff08;黄昆&#xff09; 晶格周期性的函数 记晶格基矢 a 1 , a 2 , a 3 a_1, a_2, a_3 a1​,a2​,a3​和倒格矢 b 1 , b 2 , b 3 b_1,b_2,b_3 b1​,b2​,b3​。一个具有晶格周期性的函数可以定…