栈和队列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内网映射工…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
Python 高效图像帧提取与视频编码:实战指南
Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...
ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...
用递归算法解锁「子集」问题 —— LeetCode 78题解析
文章目录 一、题目介绍二、递归思路详解:从决策树开始理解三、解法一:二叉决策树 DFS四、解法二:组合式回溯写法(推荐)五、解法对比 递归算法是编程中一种非常强大且常见的思想,它能够优雅地解决很多复杂的…...
