栈和队列OJ

一、括号的匹配

题目介绍:

思路:

  1. 如果 c 是左括号,则入栈 push;
  2. 否则通过哈希表判断括号对应关系,若 stack 栈顶出栈括号 stack.pop() 与当前遍历括号 c 不对应,则提前返回 false。
  3. 栈 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);
*/

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

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

相关文章

threejs得WebGLRenderer+CSS3DRenderer结合使用

文章目录 概要1:CSS3DRendererWebGLRenderer出现鬼畜bug2:解决思路3:代码示例小结 概要 在使用threejs显示label发现,人家自带了CSS3DRenderer/CSS2DRenderer. 1:CSS3DRendererWebGLRenderer出现鬼畜bug 第一种&…

(10)(10.8) 固件下载

文章目录 ​​​​​​​前言 10.8.1 固件 10.8.2 Bootloader 10.8.3 APM2.x Autopilot 10.8.4 许可证 10.8.5 安全 前言 固件服务器(firmware server)可提供所有飞行器的最新固件。其中包括: CopterPlaneRoverAntennaTrackerSub 本页提供了一些被视为&quo…

JavaWeb | 常用的HTML(JavaWeb)标签

目录: HTML简介HTML的基本结构HTML的常用标签:“标题” 标签“换行” 标签“段落” 标签“水平线” 标签“文字” 标签“粗体” 标签“下划线” 标签“斜体” 标签“上标” 标签“下标” 标签“闪烁” 标签表示 “空格”“列表” 标签:无序列…

window 常用基础命令

0、起步 0-1) 获取命令的参数指引 netstat /? 0-2) 关于两个斜杠: window 文件路径中使用反斜杠:\ linux 文件路径中使用:/ 1、开关机类指令 shutdown /s # 关机shutdown /r # 重启shutdown /l …

java 常用 jar 包

1 Lombok 是一个 java 类库,它利用注解方式自动生成 java bean 中 getter、setter、equals 等方法,还能自动生成 logger、toString、hashCode、builder 等 日志相关变量、Object 类方法或设计模式相关的方法,能够让你的 代码更简洁&#xff0…

C# void 关键字学习

C#中void关键字是System.Void的别名; 可以将 void 用作方法(或本地函数)的返回类型来指定该方法不返回值; 如果C#方法中没有参数,则不能将void用作参数;这是与C语言不同的,C语言有…

机器人制作开源方案 | 桌面级全向底盘--本体说明+驱动控制

一、本体说明 1. 底盘概述 该底盘是一款模块化的桌面级应用型底盘,基于应用级软件架构设计、应用级硬件系统设计、典型应用型底盘机械系统设计。 底盘本体为一个采用半独立刚性悬挂的四驱全向底盘。 2. 软件环境介绍 操作系统:Ubuntu18.04系统。基于Deb…

【STM32】学习笔记(串口通信)

串口通信 通信接口硬件电路电平标准USARTUSART框图 通信接口 串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信 单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信&#…

多线程与高并发——并发编程(4)

文章目录 四、阻塞队列1 基础概念1.1 生产者消费者概念1.2 JUC阻塞队列的存取方法2 ArrayBlockingQueue2.1 ArrayBlockingQueue的基本使用2.2 生产者方法实现原理2.2.1 ArrayBlockingQueue的常见属性2.2.2 add方法2.2.3 offer方法2.2.4 offer(time,unit)方法2.2.5 put方法2.3 消…

深入浅出AXI协议(5)——数据读写结构读写响应结构

目录 一、前言 二、写选通(Write strobes) 三、窄传输(Narrow transfers) 1、示例1 2、示例2 四、字节不变性(Byte invariance) 五、未对齐的传输(Unaligned transfers) 六…

MySQL基本查询

MySQL基本查询 表的增删查改Create(增)Retrieve(查)select列全列查询指定列查询查询字段为表达式为查询结果指定别名结果去重 where 条件英语不及格的同学的英语成绩语文成绩在 [80, 90] 分的同学及语文成绩数学成绩是 58 或者 59 或者 98 或者 99 分的同…

React的 虚拟DOM创建

React是一个流行的JavaScript库,用于构建用户界面。它通过使用虚拟DOM来提高性能和渲染速度。本文将详细介绍React的虚拟DOM的创建方式、用法和案例,以及相关代码和解释。 虚拟DOM是什么? 虚拟DOM是React的一个重要概念,它是一个…

华为云服务

【计算】 弹性云服务器ECS 弹性云服务器(Elastic Cloud Server,ECS)是由CPU、内存、操作系统、云硬盘组成的基础的计算组件。弹性云服务器创建成功后,您就可以像使用自己的本地PC或物理服务器一样,在云上使用弹性云服…

查看 Linux 配置

目录 1. 查看 Linux 配置1.1. CPU1.2. 内存 1. 查看 Linux 配置 1.1. CPU cat proc/cpuinfolscpu1.2. 内存 freetop# htop 是 top 的一个增强版, 它提供了更多的功能和可视化界面。在终端中输入以下命令即可查看: htop; # htop 界面中, 可以看到系统中运行的进程, 以及它们占…

【C#项目实战】控制台游戏——勇士斗恶龙(1)

君兮_的个人主页 即使走的再远,也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们,这里是君兮_,最近开始正式的步入学习游戏开发的正轨,想要通过写博客的方式来分享自己学到的知识和经验,这就是开设本专栏的目的。希望…

因为axios请求后端,接收不到token的问引出的问题

vue axios请求后端接受不到token的问题。 相关概念 什么是跨域? 跨域指的是在浏览器环境下,当发起请求的域(或者网站)与请求的资源所在的域之间存在协议、主机或端口中的任何一个条件不同的情况。换句话说,只要协议、…

ubuntu下Anaconda安装与使用教程

前言 好久没用anaconda了,还记得之前用anaconda的欢乐时光。pytorch和paddlepaddle(飞浆),怀念,可生活(换了ubuntu系统之后)教会了我残忍(可能很难有机会再用windows的anaconda了)。找个时间&a…

爬虫源码---爬取小猫猫交易网站

前言: 本片文章主要对爬虫爬取网页数据来进行一个简单的解答,对与其中的数据来进行一个爬取。 一:环境配置 Python版本:3.7.3 IDE:PyCharm 所需库:requests ,parsel 二:网站页面 我们需要…

MSSQL-2008的备份恢复操作

MSSQL2008清理log事务 ---------------------------------- USE [master] go ALTER DATABASE GTD SET RECOVERY SIMPLE WITH NO_WAIT GO ALTER DATABASE GTD SET RECOVERY SIMPLE --简单模式 GO USE GTD GO DBCC SHRINKFILE (NGTD _Log , 11, TRUNCATEO…

【LeetCode】208.实现Trie(前缀树)

题目 Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。 请你实现 Trie 类: Trie() 初始化前缀…