栈和队列常见oj题(括号匹配问题、栈实现队列、队列实现栈、设计循环队列)
一、括号匹配问题
1、题目要求:
2、大体思路
遍历这个字符串,如果是左括号就让它入栈,如果是右括号就让它和栈顶元素进行匹配(前提是栈中有元素),匹配成功的话就让栈顶元素出栈,匹配失败就返回false,直到遍历完字符串,如果遍历完了栈中没有元素,则返回true。
3、代码实现
bool isValid(char * s){Stack stack;StackInit(&stack);//初始化int i = 0;while(s[i] != '\0'){//入栈if(s[i] == '{' || s[i] == '[' || s[i] == '('){StackPush(&stack,s[i]);}else{//栈为空时if(StackEmpty(&stack)){StackDestroy(&stack); //销毁栈return false;}if((StackTop(&stack) == '(' && s[i] == ')') ||(StackTop(&stack) == '{' && s[i] == '}') ||(StackTop(&stack) == '[' && s[i] == ']')){ StackPop(&stack); //匹配的话出栈}else{//不匹配StackDestroy(&stack);return false;}}i++;}//遍历完后栈为空if(StackEmpty(&stack)){StackDestroy(&stack);return true;}StackDestroy(&stack);return false;
}
二、用队列实现栈
1、题目要求:
2、大体思路
用两个队列q1和q2来实现,要实现入栈的话可以选不为空的队列进行入队列操作(开始两个队列都可以),假设现在元素都在q1中,要实现出栈的话把q1中的元素放入q2中,直到q1中剩一个一个元素,在让它出队列。
3、代码实现
//用两个队列实现栈
typedef struct {Queue q1;Queue q2;
} MyStack;MyStack* myStackCreate() {MyStack* ms = (MyStack*)malloc(sizeof(MyStack));if(ms == NULL){return NULL;}QueueInit(&ms->q1);QueueInit(&ms->q2);return ms;
}void myStackPush(MyStack* obj, int x) {//给不为空的队列加入元素,模拟入栈if(QueueEmpty(&obj->q1) ){QueuePush(&obj->q2,x);}else{QueuePush(&obj->q1,x);}
}int myStackPop(MyStack* obj) {//当q1为空时,把q2中的元素放入q1中直到q2中只剩一个元素,然后q2再出队列,模拟出栈int ret = 0;if(QueueEmpty(&obj->q1)){while(QueueSize(&obj->q2) != 1){QueuePush(&obj->q1,QueueFront(&obj->q2));QueuePop(&obj->q2);}ret = QueueFront(&obj->q2);QueuePop(&obj->q2);}else{while(QueueSize(&obj->q1) != 1){QueuePush(&obj->q2,QueueFront(&obj->q1));QueuePop(&obj->q1);}ret = QueueFront(&obj->q1);QueuePop(&obj->q1);}return ret;
}
//栈顶元素相当于是队尾元素
int myStackTop(MyStack* obj) {if(QueueEmpty(&obj->q1)){return QueueBack(&obj->q2);}else{return QueueBack(&obj->q1);}
}bool myStackEmpty(MyStack* obj) {if(QueueSize(&obj->q1) == 0 && QueueSize(&obj->q2) == 0){return true;}return false;
}void myStackFree(MyStack* obj) {QueueDestroy(&obj->q1);QueueDestroy(&obj->q2);free(obj);
}
三、用栈实现队列
1、题目要求
2、大体思路
用两个栈s1和s2来实现,s1用来模拟入队列,s2用来模拟出队列。实现入队列就直接对s1进行入栈操作;出队列的话,先判断s2中是否有元素,如果没有则把s1中的元素放入s2中,然后再对s2进行出栈操作。
3、代码实现
typedef struct {//s1用来入队列,s2用来出队列Stack s1; Stack s2;
} MyQueue;MyQueue* myQueueCreate() {MyQueue* q = (MyQueue*)malloc(sizeof(MyQueue));if(q == NULL){return NULL;}StackInit(&q->s1);StackInit(&q->s2);return q;
}
//入队列
void myQueuePush(MyQueue* obj, int x) {StackPush(&obj->s1,x);
}
//出队列
int myQueuePop(MyQueue* obj) {//s2不为空的话先把s1中的元素搬移到s2中if(StackEmpty(&obj->s2)){while(!StackEmpty(&obj->s1)){StackPush(&obj->s2,StackTop(&obj->s1));StackPop(&obj->s1);}}int ret = StackTop(&obj->s2);StackPop(&obj->s2);return ret;}
//返回对头元素,和出队列差不多
int myQueuePeek(MyQueue* obj) {if(StackEmpty(&obj->s2)){while(!StackEmpty(&obj->s1)){StackPush(&obj->s2,StackTop(&obj->s1));StackPop(&obj->s1);}}return StackTop(&obj->s2);
}bool myQueueEmpty(MyQueue* obj) {if(StackEmpty(&obj->s1) && StackEmpty(&obj->s2)){return true;}return false;
}void myQueueFree(MyQueue* obj) {if(obj != NULL){StackDestroy(&obj->s1);StackDestroy(&obj->s2);free(obj);}
}
四、设计一个循环队列
1、题目要求
2、大体思路
循环队列是用顺序结构存储的。用两个指针来标记对头和队尾,如图:
但这样会有一个问题,就是在队列为空和队列满了的情况下,rear和front都重合了,这样就不能判断是队列满了还是队列为空。解决这个问题有三种方法:
方法一: 我们可以少用一个存储空间,如图所示,这样就代表队列已经满了。
方法二:用一个flag进行标记,开始设为0,插入元素时将flag设为1,删除元素时设为0;这样当front等于rear时,判断一下flag就行了。
方法三:使用一个count进行计数,只有count为零时队列为空。
3、代码实现
这里用的是方法三
typedef struct {int* array;//存储数据int front; //对头int rear; //队尾int count; //计数int N; //队列容量
} MyCircularQueue;//初始化
MyCircularQueue* myCircularQueueCreate(int k) {//先给队列申请空间MyCircularQueue* q = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));if(q == NULL ){return NULL;}//再给队列里的数组申请空间q->array = (int*)malloc(sizeof(int) * k);if(q->array == NULL){//如果失败,要先释放队列的空间,注意代码的严谨性free(q);return NULL;}q->front = q->rear = q->count = 0;q->N = k;return q;
}//判断队列是否为空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {return 0 == obj->count;
}//判断队列是否满了
bool myCircularQueueIsFull(MyCircularQueue* obj) {return obj->count == obj->N;
}//入队列
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {if(myCircularQueueIsFull(obj)){return false;}obj->array[obj->rear] = value;if(obj->rear == obj->N - 1){obj->rear = 0;}else{obj->rear++;}obj->count++;return true;
}
//出队列
bool myCircularQueueDeQueue(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return false;}if(obj->front == obj->N - 1){obj->front = 0;}else{obj->front++;}obj->count--;return true;
}int myCircularQueueFront(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return -1;}return obj->array[obj->front];
}int myCircularQueueRear(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return -1;}//注意获取队尾元素的计算方法return obj->array[(obj->rear - 1 + obj->N) % obj->N];
}//释放空间
void myCircularQueueFree(MyCircularQueue* obj) {if(obj){if(obj->array){free(obj->array);}free(obj);nhj }
}
栈和队列常见oj题(括号匹配问题、栈实现队列、队列实现栈、设计循环队列)相关推荐
- C语言【数据结构】栈和队列【OJ题(C++)、选择题】
目录 一.OJ题 1.225. 用队列实现栈 2.232. 用栈实现队列 3.622. 设计循环队列 4.20. 有效的括号 二.选择题 1.下列关于栈的叙述正确的是(B) 2.一个栈的入栈序列为AB ...
- 2.2栈的另一个应用:括号匹配
2.2栈的另一个应用:括号匹配 1.LeetCode官网 美网:https://leetcode.com/ 中文网 :https://leetcode-cn.com/ 英语不咋地,所以选择此处选择中文 ...
- 力扣题库设计循环队列
题目要求: 设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环.它也被称为"环形缓冲器". 循环队列 ...
- c++数据结构中 顺序队列的队首队尾_yiduobo的每日leetcode 622.设计循环队列
祖传的手艺不想丢了,所以按顺序写一个leetcode的题解.计划每日两题,争取不卡题吧. 622.设计循环队列https://leetcode-cn.com/problems/design-circu ...
- Leetcode 622. 设计循环队列
Leetcode 622. 设计循环队列学习 分析 代码 参考链接 分析 循环队列,自己做题时没考虑怎么实现,可以通过索引下标除以数组的长度实现循环.循环队列的队首元素和队尾元素是动态变化的,删除一个 ...
- 【Java】 LeetCode 622. 设计循环队列 (有关实现循环队列的讲解)
题目: 设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环.它也被称为"环形缓冲器". 循环队列的一 ...
- socketmq 设置队列大小_LeetCode 622:设计循环队列 Design Circular Queue
LeetCode 622:设计循环队列 Design Circular Queue 首先来看看队列这种数据结构: 队列:先入先出的数据结构 在 FIFO 数据结构中,将首先处理添加到队列中的第一个元素 ...
- 622. 设计循环队列(C实现)
题目 题目链接:622. 设计循环队列 思路 设计循环队列有两种实现方式 第一种是使用数组实现: 第二种是使用单链表实现: 而设计循环队列不管是使用数组实现还是使用单链表实现,都需要给数组预留出一个空 ...
- 力扣622,设计循环队列
文章目录 题目描述 题目分析 使用数组的方式来解题 使用链表的方式 题目描述 设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成 ...
最新文章
- BUILD 2015: Visual Studio对GitHub的支持
- [导入]ubuntu全面介绍 与 ubuntu截图
- 判断当前窗口是否是全屏的山寨版和官方版
- 学习笔记:定积分的求解(矩形法)
- 过滤器(Filter)的实现方式
- AI图像合成技术如何用于数字营销和创意领域?
- 背景动态线条js特效html5代码
- 票据识别android代码,Android 百度AI开放平台-文字识别-财务票据文字识别
- 前端webap下新增后缀名字类型。前台报错404,访问不到的解决办法是:
- ultraiso制作u盘启动盘教程图文详解
- 网络安全突发事件应急处置工作预案
- 驾考宝典java_驾考宝典java
- 【笔记】移植ezSIFT顺手搭建个全景照片合成器
- Linux下运行python自动化脚本
- 忆阻器的概念和实现原理
- 第二章 一波未平 校园江湖
- 【Proteus仿真】4X4矩阵按键显示0-F
- R语言ggplot2可视化自定义图例(legend)示例点的大小实战
- Android开发-直播视讯(2)-ijkplayer-基础知识
- 【云和恩墨大讲堂】戴明明 - 基于 PCIE 闪存卡的 Oracle 数据库使用
热门文章
- 英译汉需要注意的几点
- 照相机闪光灯的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
- 安装pycocotools时遇到ERROR: Could not build wheels for pycocotools which use PEP 517 and cannot be instal
- rust 使用 ffi 调用 C 静态链接库
- java计算机毕业设计ssm“安家”儿童福利院管理系统(源码+系统+mysql数据库+Lw文档)
- java验证文本域对IP,端口号的验证
- 局域网多媒体教学系统中基于JAVA的屏幕监控
- 【Redis过期策略/内存淘汰机制/对过期Key的处理】
- Oracle 数据库监听日志过大,怎么清除?
- 小机扩容磁盘方法(AIX 6.0)