栈和队列OJ
一、括号的匹配
题目介绍:


思路:
- 如果 c 是左括号,则入栈 push;
- 否则通过哈希表判断括号对应关系,若 stack 栈顶出栈括号 stack.pop() 与当前遍历括号 c 不对应,则提前返回 false。
- 栈 stack 为空: 此时 stack.pop() 操作会报错;因此,我们采用一个取巧方法,给 stack 赋初值 ?,并在哈希表 dic 中建立 key: ‘?’,value:’?’ 的对应关系予以配合。此时当 stack 为空且 c 为右括号时,可以正常提前返回 false
字符串 s 以左括号结尾: 此情况下可以正常遍历完整个 s,但 stack 中遗留未出栈的左括号;因此,最后需返回 len(stack) == 1,以判断是否是有效的括号组合
typedef int STDataType;
//动态存储结构
typedef struct Stack
{STDataType *a;int top;int capacity; //容量
}ST;void STInit(ST* ps); //初始化栈
void STDestory(ST* ps); //销毁栈
bool STEmpty(ST* ps); //判断是否为空
void STPush(ST* ps, STDataType x); //入栈
void STPop(ST* ps); //出栈
STDataType STTop(ST* ps); //取栈顶元素
int STSize(ST* ps); //返回栈元素个数void STInit(ST* ps) //初始化栈
{assert(ps);ps->a = NULL;ps->top = 0;ps->capacity = 0;
}void STDestory(ST* ps) //销毁栈
{assert(ps);free(ps->a);ps->a = NULL;ps->top = 0;ps->capacity = 0;
}bool STEmpty(ST* ps) //判断是否为空
{assert(ps);return (ps->top == 0);
}void STPush(ST* ps, STDataType x) //入栈
{assert(ps);//扩容if (ps->top == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* tem = (STDataType*)realloc(ps->a,sizeof(STDataType)* newcapacity);if (tem == NULL){perror("malloc");exit(-1);}ps->a = tem;ps->capacity = newcapacity;}ps->a[ps->top] = x;ps->top++;
}void STPop(ST* ps) //出栈
{assert(ps);assert(ps->top>0);--ps->top;
}STDataType STTop(ST* ps) //取栈顶元素
{assert(ps);assert(ps->top > 0);return ps->a[ps->top-1];
}int STSize(ST* ps) //返回栈元素个数
{assert(ps);return ps->top ;
}
bool isValid(char * s)
{char topval;ST st;STInit(&st);while(*s){if(*s=='('||*s=='['||*s=='{'){STPush(&st, *s);}else{if(STEmpty(&st)){STDestory(&st);return false;}topval=STTop(&st);STPop(&st);if((*s=='}'&&topval!='{')||(*s==')'&&topval!='(')||(*s==']'&&topval!='[')){STDestory(&st);return false;}}++s;}bool ret=STEmpty(&st);STDestory(&st);return ret;
}
二、队列实现栈
题目介绍:



typedef int QDataType;typedef struct QueueNode
{struct QueueNode* next;QDataType data;
}QNode;typedef struct Queue
{QNode* head; //队头指针QNode* tail; //队尾指针int size; //元素个数
}Que;void QueueInit(Que* pq); //初始化队列
void QueueDestory(Que* pq); //销毁队列
bool QueueEmpty(Que* pq); //判断队列是否为空
void QueuePush(Que* pq, QDataType x);//进队列
void QueuePop(Que* pq); //出队列
QDataType QueueFront(Que* pq); //取队头元素
QDataType QueueBack(Que* pq); //取队尾元素
int QueueSize(Que* pq); //返回元素个数
void QueueInit(Que* pq) //初始化队列
{assert(pq);pq->head = NULL;pq->tail = NULL;pq->size = 0;
}void QueueDestory(Que* pq) //销毁队列
{assert(pq);QNode* cur =pq->head;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;pq->size = 0;
}bool QueueEmpty(Que* pq) //判断队列是否为空
{assert(pq);return pq -> head == NULL;
}void QueuePush(Que* pq, QDataType x)//进队列
{//尾插assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc");exit(-1);}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++;}void QueuePop(Que* pq) //出队列
{assert(pq);assert(!QueueEmpty(pq));if (pq->head->next == NULL){free(pq->head);pq->head = pq->tail=NULL;}else{QNode* next = pq->head->next;free(pq->head);pq->head = next;}pq->size--;
}QDataType QueueFront(Que* pq) //取队头元素
{assert(pq);assert(!QueueEmpty(pq));return pq->head->data;
}QDataType QueueBack(Que* pq) //取队尾元素
{assert(pq);assert(!QueueEmpty(pq));return pq->tail->data;
}int QueueSize(Que* pq) //返回元素个数
{assert(pq);return pq->size;
}
typedef struct
{Que q1;Que q2;
} MyStack;MyStack* myStackCreate()
{MyStack*pst=(MyStack*)malloc(sizeof(MyStack));QueueInit(&pst->q1);QueueInit(&pst->q2);return pst;
}void myStackPush(MyStack* obj, int x)
{if(!QueueEmpty(&obj->q1)){QueuePush(&obj->q1,x);}else{QueuePush(&obj->q2,x);}
}int myStackPop(MyStack* obj)
{Que*empty=&obj->q1;Que*nonEmpty=&obj->q2;if(!QueueEmpty(&obj->q1)){nonEmpty=&obj->q1;empty=&obj->q2;}while(QueueSize(nonEmpty)>1){QueuePush(empty,QueueFront(nonEmpty));QueuePop(nonEmpty);}int top=QueueFront(nonEmpty);QueuePop(nonEmpty);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);
}/*** 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);
*/
三、栈实现队列
题目介绍:

思路:
因为队列先进先出,栈先进后出,所以用两个栈实现队列。栈s1用来入队,栈s2用来出队。
入队:对入队的栈s1直接进行元素入栈。
出队:当出队的栈s2不为空时,s2直接出栈;若s2为空,将s1的元素都导入出队的栈s2里,然后s2进行出栈。、
在入队1、2、3、4后出队,如图所示:s1中的数据都入栈s2(s1,s2中的数据相同,顺序相反,例:s1中的栈底元素1出现在s2中的栈顶),此时s1的top==0(top表示栈中有多少元素,0代表栈中元素都已经出栈),s2的top==3(本来有4个数据,但栈顶元素已经出栈,所以为3).
typedef int STDataType;
typedef struct Stack
{STDataType *a;int top;int capacity; //容量
}ST;void STInit(ST* ps); //初始化栈
void STDestory(ST* ps); //销毁栈
bool STEmpty(ST* ps); //判断是否为空
void STPush(ST* ps, STDataType x); //入栈
void STPop(ST* ps); //出栈
STDataType STTop(ST* ps); //取栈顶元素
int STSize(ST* ps); //返回栈元素个数void STInit(ST* ps) //初始化栈
{assert(ps);ps->a = NULL;ps->top = 0;ps->capacity = 0;
}void STDestory(ST* ps) //销毁栈
{assert(ps);free(ps->a);ps->a = NULL;ps->top = 0;ps->capacity = 0;
}bool STEmpty(ST* ps) //判断是否为空
{assert(ps);return (ps->top == 0);
}void STPush(ST* ps, STDataType x) //入栈
{assert(ps);//扩容if (ps->top == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* tem = (STDataType*)realloc(ps->a,sizeof(STDataType)* newcapacity);if (tem == NULL){perror("malloc");exit(-1);}ps->a = tem;ps->capacity = newcapacity;}ps->a[ps->top] = x;ps->top++;
}void STPop(ST* ps) //出栈
{assert(ps);assert(ps->top>0);--ps->top;
}STDataType STTop(ST* ps) //取栈顶元素
{assert(ps);assert(ps->top > 0);return ps->a[ps->top-1];
}int STSize(ST* ps) //返回栈元素个数
{assert(ps);return ps->top ;
}
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)
{STPush(&obj->pushst,x);
}int myQueuePeek(MyQueue* obj) //取对头数据
{if(STEmpty(&obj->popst)){while(!STEmpty(&obj->pushst)){STPush(&obj->popst,STTop(&obj->pushst));STPop(&obj->pushst);}}return STTop(&obj->popst);
}int myQueuePop(MyQueue* obj)
{int front =myQueuePeek(obj);STPop(&obj->popst);return front;
}bool myQueueEmpty(MyQueue* obj)
{return STEmpty(&obj->popst)&&STEmpty(&obj->pushst);
}void myQueueFree(MyQueue* obj)
{STDestory(&obj->popst);STDestory(&obj->pushst);free(obj);
}/*** 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);
*/
四、循环队列
题目介绍:


设计一个队列,这个队列的大小是固定的,且队列头尾相连, 然后该队列能够实现题目中的操作。
那么是使用数组实现,还是用链表实现呢?我们接着往下看。
环形队列的几个判断条件
front:指向队列的第一个元素,初始值front=0
rear: 指向队列的最后一个元素的后一个位置(预留一个空间作为约定),初始值rear=0
maxSize: 数组的最大容量
队空:front == rear
队满:(rear+1)%maxSize == front
队列中的有效数据个数:(rear+maxSize-front)% maxSize
其中判断队列满的思想的话,可以看下图,因为是环形的,起初front=rear=0,每当添加元素时,将rear++,但是其实预留了一个长度没有用,比如定义的队列数组长度为5时,但是实际上可以使用的地址就是0,1,2,3,此时rear=4, 4这个空间用来判断队满的条件(rear+1)%maxSize==front


有了上面的铺垫就可以很轻松的写出下面的函数。
typedef struct
{int *a;int front;int rear;int k;
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k)
{MyCircularQueue*obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));//多开一个空间(浪费掉)为了区分空和满obj->a=(int*)malloc(sizeof(int)*(k+1));obj->front=obj->rear=0;obj->k=k;return obj;
}bool myCircularQueueIsEmpty(MyCircularQueue* obj)
{return obj->front==obj->rear;
}bool myCircularQueueIsFull(MyCircularQueue* obj)
{return (obj->rear+1)%(obj->k+1)==obj->front;
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)
{if(myCircularQueueIsFull(obj)){return false;}obj->a[obj->rear]=value;obj->rear++;obj->rear%=(obj->k+1);return true;
}bool myCircularQueueDeQueue(MyCircularQueue* obj)
{if(myCircularQueueIsEmpty(obj)){return false;}++obj->front;obj->front%=(obj->k+1);return true;
}int myCircularQueueFront(MyCircularQueue* obj)
{if(myCircularQueueIsEmpty(obj)){return -1;}return obj->a[obj->front];
}int myCircularQueueRear(MyCircularQueue* obj)
{if(myCircularQueueIsEmpty(obj)){return -1;}return obj->a[(obj->rear+(obj->k+1)-1)%(obj->k+1)];
}void myCircularQueueFree(MyCircularQueue* obj)
{free(obj->a);free(obj);
}/*** Your MyCircularQueue struct will be instantiated and called as such:* MyCircularQueue* obj = myCircularQueueCreate(k);* bool param_1 = myCircularQueueEnQueue(obj, value);* bool param_2 = myCircularQueueDeQueue(obj);* int param_3 = myCircularQueueFront(obj);* int param_4 = myCircularQueueRear(obj);* bool param_5 = myCircularQueueIsEmpty(obj);* bool param_6 = myCircularQueueIsFull(obj);* myCircularQueueFree(obj);
*/
相关文章:
栈和队列OJ
一、括号的匹配 题目介绍: 思路: 如果 c 是左括号,则入栈 push;否则通过哈希表判断括号对应关系,若 stack 栈顶出栈括号 stack.pop() 与当前遍历括号 c 不对应,则提前返回 false。栈 stack 为空࿱…...
Bootstrap的CSS类积累学习
要看哪个的介绍,搜索关键词就行了。 001-container 这是Bootstrap中定义的一个CSS类,它用于创建一个具有固定宽度的容器。比如,container类将<div>元素包装成一个固定宽度的容器。详情见:https://blog.csdn.net/wenhao_ir…...
Scala的集合操作之可变数组和不可变数组,可变List集合与不可变List集合,可变Set与不可变Set操作,可变和不可变Map集合和元组操作
Scala的集合操作之,可变数组和不可变数组,可变List集合与不可变List集合 不可变数组 /* traversable/ˈtrvəsəbl/adj.能越过的;可否认的*/ object Test01_ImmutableArray {def main(args: Array[String]): Unit {// 1. 创建数组val arr:…...
优化Docker权限管理:配置Docker用户组
Docker 利用 Linux 的用户和组权限来管理对 Docker 守护进程的访问权限。一般情况下,只有 root 用户和属于 docker 用户组的用户才被允许访问 Docker 守护进程。在 Linux 系统上使用 Docker 时,如果您尚未配置 docker 用户组,那么作为非 root…...
python+opencv读取rtsp流
前言 在使用yolov5做物体检测中,需要拉取视频流。分解任务第一步则是需要使用opencv读取rtsp流,只要拿到每一帧图片在进行推理显示即可。 代码 import cv2 def read_rtsp():cap cv2.VideoCapture(rtsp://admin:Vrc123456192.168.2.226:554)fourcc c…...
linux入门---动静态库的加载
目录标题 为什么会有动态库和静态库静态库的实现动态库的实现动静态库的加载 为什么会有动态库和静态库 我们来模拟一个场景,首先创建两个头文件 根据文件名便可以得知add.h头文件中存放的是加法函数的声明,sub.h头文件中存放的是减法函数的声明&#…...
计算机竞赛 基于深度学习的人脸专注度检测计算系统 - opencv python cnn
文章目录 1 前言2 相关技术2.1CNN简介2.2 人脸识别算法2.3专注检测原理2.4 OpenCV 3 功能介绍3.1人脸录入功能3.2 人脸识别3.3 人脸专注度检测3.4 识别记录 4 最后 1 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 基于深度学习的人脸专注度…...
【Yolov5+Deepsort】训练自己的数据集(3)| 目标检测追踪 | 轨迹绘制 | 报错分析解决
📢前言:本篇是关于如何使用YoloV5Deepsort训练自己的数据集,从而实现目标检测与目标追踪,并绘制出物体的运动轨迹。本章讲解的为第三部分内容:数据集的制作、Deepsort模型的训练以及动物运动轨迹的绘制。本文中用到的数…...
docker desktop如何一键进入容器内部
对着对应的容器 点击 view files...
多机单目标跟踪Cross-Drone Transformer Network for Robust Single Object Tracking
1. 摘要 无人机已被广泛用于各种应用,如空中摄影和军事安全,因为与固定摄像机相比,无人机具有高机动性和广阔的视野。多架无人机跟踪系统可以通过收集不同视角的互补视频片段来提供丰富的目标信息,特别是当目标在某些视角下被遮挡…...
手写Mybatis:第7章-SQL执行器的定义和实现
文章目录 一、目标:SQL执行的定义和实现二、设计:SQL执行的定义和实现三、实现:SQL执行的定义和实现3.1 工程结构3.2 SQL执行实现的关系图3.3 执行器的定义和实现3.3.1 Executor 接口3.3.2 BaseExecutor 抽象基类3.3.3 SimpleExecutor 简单执…...
C语言基础知识理论版(很详细)
文章目录 前述一、数据1.1 数据类型1.2 数据第一种数据:常量第二种数据:变量第三种数据:表达式1、算术运算符及算术表达式2、赋值运算符及赋值表达式3、自增、自减运算符4、逗号运算符及其表达式(‘顺序求值’表达式)5…...
CG MAGIC分享3d Max中的Corona渲染器材质如何成转换VRay材质?
大家无论是使用Corona渲染器还是Vray渲染器时,进行材质问题时,都会遇到转化材质问题。 如何将CR转换成VR或者将VR转换CR材质呢? 对于这两者之间转换最好最好的方法只能是材质转换器。 CG MAGIC小编,梳理了两种方法,大…...
电脑入门:路由器常见问题排错步骤
HiPER系列路由器使用中Ping LAN口不通的诊断步骤 准备工作: 在可以ping通的时候记录下路由器LAN口的MAC地址: 命令hiper% show interface ethernet/1 mac Mac : 0022aa419d1e 以下步骤在ping不通路由器的时候依次操作,并记下结果: 步骤一:观察设备各端口…...
mac电脑识别不出来u盘?mac识别不了u盘怎么办
有些用户反馈说本来想要拷贝文件,但是将U盘插入mac系统后竟然不能识别,这时候我们需要用到NTFS For Mac软件。 其实mac系统只提供了它自身磁盘格式(mac os 扩展)等的读写权限,只提供了读的权限给NTFS、FAT32给硬盘和U盘,我们99%使…...
【系统编程】线程池以及API接口简介
(꒪ꇴ꒪ ),Hello我是祐言QAQ我的博客主页:C/C语言,数据结构,Linux基础,ARM开发板,网络编程等领域UP🌍快上🚘,一起学习,让我们成为一个强大的攻城狮࿰…...
Verilog零基础入门(边看边练与测试仿真)-笔记
文章目录 第一讲第二讲第三讲第四讲 第一讲 1、testbench 没有端口,所以没括号 2、testbench 输入端 之后要变动 所以定义为reg 3、#10 :过10个时间单位 ;’timescale 1ns/10ps 即 1ns 的时间单位 10ps的时间精度 4、reg 型变量赋值的时候 用…...
LLMs之Code:Code Llama的简介、安装、使用方法之详细攻略
LLMs之Code:Code Llama的简介、安装、使用方法之详细攻略 导读:2023年08月25日(北京时间),Meta发布了Code Llama,一个可以使用文本提示生成代码的大型语言模型(LLM)。Code Llama是最先进的公开可用的LLM代码任务,并有潜…...
[国产MCU]-W801开发实例-MQTT客户端通信
MQTT客户端通信 文章目录 MQTT客户端通信1、MQTT介绍2、W801的MQTT客户端相关API介绍3、代码实现本文将详细介绍如何在W801中使用MQTT协议通信。 1、MQTT介绍 MQTT 被称为消息队列遥测传输协议。它是一种轻量级消息传递协议,可通过简单的通信机制帮助资源受限的网络客户端。 …...
搭建个人hMailServer 邮件服务实现远程发送邮件
文章目录 1. 安装hMailServer2. 设置hMailServer3. 客户端安装添加账号4. 测试发送邮件5. 安装cpolar6. 创建公网地址7. 测试远程发送邮件8. 固定连接公网地址9. 测试固定远程地址发送邮件 hMailServer 是一个邮件服务器,通过它我们可以搭建自己的邮件服务,通过cpolar内网映射工…...
【笔试真题】- 招商银行-2026.03.30
📌 点击直达笔试专栏 👉《大厂笔试突围》 💻 春秋招笔试突围在线OJ 👉 笔试突围在线刷题 bishipass.com 招商银行-2026.03.30 1. 术语接龙计分 问题描述 招商银行的培训平台里有一个简化版“术语接龙”小游戏。 系统维护了一份单词表,并给定一个当前单词。用户之…...
Qwen3.5-9B惊艳效果:上传物理实验图→识别仪器→生成操作步骤视频脚本
Qwen3.5-9B惊艳效果:上传物理实验图→识别仪器→生成操作步骤视频脚本 1. 模型能力概览 Qwen3.5-9B是一款拥有90亿参数的开源大语言模型,在多模态理解和逻辑推理方面表现出色。这个模型最令人惊艳的能力在于它能够: 准确识别实验仪器&…...
GME-Qwen2-VL-2B自动化测试:基于模型视觉理解的GUI界面测试脚本
GME-Qwen2-VL-2B自动化测试:基于模型视觉理解的GUI界面测试脚本 1. 引言 你有没有遇到过这样的场景?辛辛苦苦写了一套UI自动化测试脚本,结果软件界面稍微改个按钮颜色、挪个位置,整个测试就全挂了。维护成本高得吓人,…...
智慧卤味,一码追溯:万界星空MES方案
一、行业痛点与MES目标1、主要痛点生产依赖经验:卤制时间、温度、配料比例依赖人工经验,产品口味和质量不稳定。追溯困难:一旦出现食品安全问题,难以快速精准追溯到问题源头(原料批次、生产环节、操作人员等࿰…...
从零构建uWSGI-Nginx-Flask-Docker镜像的5个核心步骤
从零构建uWSGI-Nginx-Flask-Docker镜像的5个核心步骤 【免费下载链接】uwsgi-nginx-flask-docker Docker image with uWSGI and Nginx for Flask applications in Python running in a single container. Optionally with Alpine Linux. 项目地址: https://gitcode.com/gh_mi…...
Comsol 脉冲激光诱导等离子体仿真模型:探索微观世界的奇妙之旅
Comsol脉冲激光诱导等离子体仿真模型 利用脉冲激光作为热源,在氩气环境中诱导产生等离子体,主要体现出等离子体的密度、等离子体温度等参数 可以为激光诱导等离子体提供准确的参考在科研与工程领域,对脉冲激光诱导等离子体的深入研究有着举足…...
PakePlus云打包入门指南:从零到一的GitHub Token配置与安全实践
PakePlus云打包入门指南:从零到一的GitHub Token配置与安全实践 【免费下载链接】PakePlus Turn any webpage/HTML/Vue/React and so on into desktop and mobile app under 5M with easy in few minutes. 轻松将任意网站/HTML/Vue/React等项目构建为轻量级(小于5M)…...
自指宇宙学形式化验证套件 (Coq‑SRU v1.2.0)
自指宇宙学形式化验证套件 (Coq‑SRU v1.2.0)技术摘要 正式整编版 项目标识:Coq Formalization of Self‑Referential Universe (Coq‑SRU) 版本:v1.2.0(对齐《世毫九自指宇宙学》理论第三部分) 代码仓库:https://git…...
ANSYS CFX 自定义函数实战:数据导入与变量创建全流程
1. ANSYS CFX自定义函数入门指南 第一次接触CFX自定义函数时,我也被那一堆参数和选项搞得晕头转向。但实际用下来发现,这玩意儿就像给计算流体力学(CFD)分析装了个"外挂",能让你在标准功能之外实现各种个性化需求。简单来说&#x…...
Virtual-Display-Driver:Windows虚拟显示器的全能解决方案深度解析
Virtual-Display-Driver:Windows虚拟显示器的全能解决方案深度解析 【免费下载链接】Virtual-Display-Driver Add virtual monitors to your windows 10/11 device! Works with VR, OBS, Sunshine, and/or any desktop sharing software. 项目地址: https://gitco…...
