数据结构第七讲:栈和队列OJ题

数据结构第七讲:栈和队列OJ题

  • 1.有效的括号
  • 2.用队列实现栈
  • 3.用栈实现队列
  • 4.设计循环队列

1.有效的括号

链接: OJ题目链接
在这里插入图片描述

typedef char StackDataType;typedef struct Stack
{StackDataType* arr;//使用一个指针来指向开辟的数组int capacity;//保存数组的空间大小int top;//指向栈顶
}Stack;//栈的初始化
void Init(Stack* ps)
{assert(ps);ps->arr = NULL;ps->capacity = ps->top = 0;
}//栈的销毁
void Destory(Stack* ps)
{assert(ps);//注意:这个要加上if进行判断,为了确保arr数组不是指向NULLif(ps->arr)free(ps->arr);ps->arr = NULL;ps->capacity = ps->top = 0;
}//栈的插入
void StackPush(Stack* ps, StackDataType x)
{assert(ps);//因为只有栈的插入才需要开辟空间,所以开辟结点空间不必封装成一个函数if (ps->top == ps->capacity){//空间不足,需要开辟int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;StackDataType* parr = (StackDataType*)realloc(ps->arr, newcapacity * sizeof(StackDataType));if (parr == NULL){perror("malloc faile!");exit(1);}ps->arr = parr;ps->capacity = newcapacity;}ps->arr[ps->top++] = x;
}//栈的删除
void StackPop(Stack* ps)
{//栈为NULL时不能删除,栈中没有数据时不能删除assert(ps && ps->top);--ps->top;
}//取栈顶元素
StackDataType StackPrint(Stack* ps)
{assert(ps && ps->top);return ps->arr[--ps->top];
}//获取栈中有效元素个数
int StackSize(Stack* ps)
{assert(ps);return ps->top;
}--------------------------------------------------------------------------
//下面才是实现思路
bool isValid(char* s) {Stack ps;//先对栈进行初始化Init(&ps);while(*s){if(*s=='(' || *s=='{' || *s=='['){//三种情况,进行插入StackPush(&ps, *s);}else{if((ps.top == 0) || (ps.top==0 && *s!='\0')) return false;StackDataType a = StackPrint(&ps);if( (a=='(' && *s==')') ||  (a=='[' && *s==']') ||(a=='{' && *s=='}') );else{//不匹配时,直接返回falsereturn false;}}s++;}if(ps.top!=0 && *s=='\0') return false;return true;
}

2.用队列实现栈

链接: OJ题目链接
在这里插入图片描述
在这里插入图片描述

//结点结构体
typedef int QueueDataType;typedef struct QueueNode
{//和链表一样,也需要结点进行链接QueueDataType val;struct QueueNode* next;
}QueueNode;//队列结构体
typedef struct Queue
{QueueNode* head;//指向队列的头部,方便删除数据QueueNode* tail;//指向队列的尾部,方便插入数据int size;//用来记录有效数据的个数
}Queue;//队列初始化
void Init(Queue* pq)
{assert(pq);pq->head = pq->tail = NULL;pq->size = 0;
}//销毁队列
void Destory(Queue* pq)
{assert(pq);QueueNode* prev = pq->head;while (prev){   QueueNode* next = prev->next;free(prev);prev = next;}pq->head = pq->tail = NULL;pq->size = 0;
}//入队列
void QueuePush(Queue* pq, QueueDataType x)
{assert(pq);//只有入队列需要开辟结点空间QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));if (newnode == NULL){perror("malloc faile!");exit(1);}newnode->val = x;newnode->next = NULL;//要分情况讨论:当队列一开始没有一个结点时if (pq->head == NULL){pq->head = pq->tail = newnode;}else{//直接插入到末尾即可//head ... tail newnodepq->tail->next = newnode;pq->tail = newnode;}pq->size++;
}//出队列
void QueuePop(Queue* pq)
{assert(pq && pq->head);//出队列要求从队列开头进行删除//此时要分情况讨论:当只具有一个结点时if (pq->head == pq->tail){free(pq->head);pq->head = pq->tail == NULL;}else{//pq->head pq->head->nextQueueNode* tmp = pq->head->next;free(pq->head);pq->head = tmp;}--pq->size;
}//取队列头结点数据
QueueDataType QueueFront(Queue* pq)
{assert(pq && pq->head);return pq->head->val;
}//取队列尾节点数据
QueueDataType QueueBack(Queue* pq)
{assert(pq && pq->head && pq->tail);return pq->tail->val;
}//队列有效元素的个数
int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}//检查队列是否为空
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->head == NULL;
}
///
typedef struct {//需要创建两个队列Queue q1;Queue q2;
} MyStack;MyStack* myStackCreate() {MyStack* pst = (MyStack*)malloc(sizeof(MyStack));Init(&pst->q1);Init(&pst->q2);return pst;
}void myStackPush(MyStack* obj, int x) {//将数据压入栈,首先要找到那个不为空的队列//假设第一个队列不为空Queue* none = &obj->q1;Queue* emp = &obj->q2;if(QueueEmpty(&obj->q1)){none = &obj->q2;emp = &obj->q1;}QueuePush(none, x);
}int myStackPop(MyStack* obj) {//出栈Queue* none = &obj->q1;Queue* emp = &obj->q2;if(QueueEmpty(&obj->q1)){none = &obj->q2;emp = &obj->q1;}//先将size-1个数据保存到空的队列中while(QueueSize(none) > 1){int data = QueueFront(none);QueuePush(emp, data);QueuePop(none);}int data = QueueFront(none);QueuePop(none);return data;
}int myStackTop(MyStack* obj) {//取栈顶元素Queue* none = &obj->q1;Queue* emp = &obj->q2;if(QueueEmpty(&obj->q1)){none = &obj->q2;emp = &obj->q1;}return QueueBack(none);
}bool myStackEmpty(MyStack* obj) {return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}void myStackFree(MyStack* obj) {Destory(&obj->q1);Destory(&obj->q2);free(obj);obj = NULL;
}

3.用栈实现队列

链接: OJ题目链接
在这里插入图片描述
在这里插入图片描述

typedef int StackDataType;typedef struct Stack
{StackDataType* arr;//使用一个指针来指向开辟的数组int capacity;//保存数组的空间大小int top;//指向栈顶
}Stack;//栈的初始化
void Init(Stack* ps)
{assert(ps);ps->arr = NULL;ps->capacity = ps->top = 0;
}//栈的销毁
void Destory(Stack* ps)
{assert(ps);//注意:这个要加上if进行判断,为了确保arr数组不是指向NULLif(ps->arr)free(ps->arr);ps->arr = NULL;ps->capacity = ps->top = 0;
}//栈的插入
void StackPush(Stack* ps, StackDataType x)
{assert(ps);//因为只有栈的插入才需要开辟空间,所以开辟结点空间不必封装成一个函数if (ps->top == ps->capacity){//空间不足,需要开辟int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;StackDataType* parr = (StackDataType*)realloc(ps->arr, newcapacity * sizeof(StackDataType));if (parr == NULL){perror("malloc faile!");exit(1);}ps->arr = parr;ps->capacity = newcapacity;}ps->arr[ps->top++] = x;
}//栈的删除
void StackPop(Stack* ps)
{//栈为NULL时不能删除,栈中没有数据时不能删除assert(ps && ps->top);--ps->top;
}//取栈顶元素
StackDataType StackPrint(Stack* ps)
{assert(ps && ps->top);return ps->arr[ps->top-1];
}//获取栈中有效元素个数
int StackSize(Stack* ps)
{assert(ps);return ps->top;
}//检查栈是否为空
bool StackCheck(Stack* ps)
{assert(ps);return ps->top == 0;
}
/
typedef struct {//首先要创建出两个栈结构体Stack push;Stack pop;
} MyQueue;MyQueue* myQueueCreate() {MyQueue* queue = (MyQueue*)malloc(sizeof(MyQueue));Init(&queue->push);Init(&queue->pop);return queue;
}void myQueuePush(MyQueue* obj, int x) {StackPush(&obj->push, x);
}int myQueuePop(MyQueue* obj) {//删除元素要在pop队列中删除//此时要进行讨论//当pop链表还不为空时,直接删除一个元素即可if(!StackCheck(&obj->pop)){int data = StackPrint(&obj->pop);StackPop(&obj->pop);return data;}//当pop链表为空时,需要将push链表中的数据移到pop链表中//先将元素全部移到pop队列中while(!StackCheck(&obj->push)){int data = StackPrint(&obj->push);StackPush(&obj->pop, data);StackPop(&obj->push);}//然后删除pop中的一个元素即可int data = StackPrint(&obj->pop);StackPop(&obj->pop);return data;
}int myQueuePeek(MyQueue* obj) {//返回队列开头的元素//此时也要进行检查if(!StackCheck(&obj->pop)){return StackPrint(&obj->pop);}//当pop链表为空时,需要将push链表中的数据移到pop链表中//先将元素全部移到pop队列中while(!StackCheck(&obj->push)){int data = StackPrint(&obj->push);StackPush(&obj->pop, data);StackPop(&obj->push);}return StackPrint(&obj->pop);
}bool myQueueEmpty(MyQueue* obj) {//检查队列是否为空return StackCheck(&obj->push) && StackCheck(&obj->pop);
}void myQueueFree(MyQueue* obj) {Destory(&obj->push);Destory(&obj->pop);free(obj);obj = NULL;
}

4.设计循环队列

链接: OJ题目链接
要区分队列已满和队列中无数据就要多开辟一块空间,但是那一块空间只是一个指代作用,其实并不会被使用

在这里插入图片描述

在这里插入图片描述

typedef struct {int *arr;int front;int rear;int capacity;
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* tmp = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));//需要多创建一个int字节的空间,因为后边还要使用tmp->arr = (int*)malloc(sizeof(int) * (k+1));tmp->front = tmp->rear = 0;tmp->capacity = k;return tmp;
}//判断循环队列是否已满
bool myCircularQueueIsFull(MyCircularQueue* obj) {return (obj->rear + 1) % (obj->capacity + 1) == obj->front;
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {//当队列已满时不能进行插入数据if(myCircularQueueIsFull(obj)){return false;}//当循环队列不满时,在rear位置插入数据即可obj->arr[obj->rear++] = value;//如果rear的结果超出了数组的大小,要对rear的值进行一个更正obj->rear %= (obj->capacity+1);return true;
}//判断队列是否为空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {return obj->rear == obj->front;
}bool myCircularQueueDeQueue(MyCircularQueue* obj) {//删除数据时直接移动front的指向即可//当队列为空时不能够执行删除操作if(myCircularQueueIsEmpty(obj));{return false;}obj->front++;//对front的位置进行校正obj->front %= (obj->capacity+1);return true;
}int myCircularQueueFront(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return -1;}return obj->arr[obj->front];
}int myCircularQueueRear(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return -1;}int prev = obj->rear - 1;if (obj->rear == 0){prev = obj->capacity - 1;}return obj->arr[prev];
}void myCircularQueueFree(MyCircularQueue* obj) {free(obj->arr);free(obj);obj = NULL;
}

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

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

相关文章

springboot爱宠屋宠物商店管理系统-计算机毕业设计源码52726

目录 摘要 1 绪论 1.1 选题背景与意义 1.2国内外研究现状 1.3论文结构与章节安排 2系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1系统开发流程 2.2.2 用户登录流程 2.2.3 系统操作流程 2.2.4 添加信息流程 2.2.5 修改信息流程 2.2.6 删除信息流程 2.3 系统功能…

【机器学习】正规方程的简单介绍以及如何使用Scikit-Learn实现基于正规方程的闭式解线性回归

引言 Scikit-learn 是一个开源的机器学习库,它支持 Python 编程语言。它提供了多种机器学习算法的实现,并用于数据挖掘和数据分析 文章目录 引言一、正规方程的定义二、正规方程的原理三、使用 Scikit-Learn 实现基于正规方程的闭式解线性回归3.1 工具3.…

实验15.多线程调度

简介 实验.多线程调度 内核线程 1.在时钟中断函数中处理中,减少当前线程pcb的tick,tick为0则启动调度2.调度,把当前线程pcb放入就绪对立队尾,把就绪线程队首拿出来执行主要代码 引导 省略内核 list.h #ifndef __LIB_KERNEL_…

【2024最新】 服务器安装Ubuntu20.04 (安装教程、常用命令、故障排查)持续更新中.....

安装教程(系统、NVIDIA驱动、CUDA、CUDNN、Pytorch、Timeshift、ToDesk、花生壳) 制作U盘启动盘,并安装系统 在MSDN i tell you下载Ubuntu20.04 Desktop 版本,并使用Rufus制作UEFI启动盘,参考UEFI安装Ubuntu使用GPTU…

mysql 的MHA

mysql 的MHA 什么是MHA 高可用模式下的故障切换,基于主从复制。 单点故障和主从复制不能切换的问题。 至少需要3台。 故障切换过程0-30秒。 vip地址,根据vip地址所在的主机,确定主备。 主 vip 备 vip 主和备不是优先确定的&#xff…

InternLM Linux 基础知识

完成SSH连接与端口映射并运行hello_world.py 创建并运行test.sh文件 使用 VSCODE 远程连接开发机并创建一个conda环境

“pandas”的坑

参考:百度安全验证 本文基于python第三方数据分析库pandas,分享这几天所遇到的3个爬坑的案例,希望对也在爬坑的同学们尽一份绵薄之力,如有错误或者写得不好的地方,烦请指正,谢谢。 01df中startswith的坑 …

led灯什么牌子的质量好?led灯护眼效果好的五款爆品分享

大家在选择led灯的时候,最关心的就是“led灯什么牌子的质量好?”市面上商家推出来的led灯品牌众多,型号以及功能也是令人眼花缭乱的,既然如此,那我们应该如何买到质量过关又好用的led灯呢?接下来我将为大家…

敏感信息泄露wp

1.右键查看网页源代码 2.前台JS绕过,ctrlU绕过JS查看源码 3.开发者工具,网络,查看协议 4.后台地址在robots,拼接目录/robots.txt 5.用dirsearch扫描,看到index.phps,phps中有源码,拼接目录,下载index.phps …

网页封装app:如何将网站转换为移动应用程序?(网页封装app)

随着移动互联网的普及,越来越多的企业开始关注移动应用程序的开发。但是,对于一些小型企业或个人,开发一款移动应用程序可能需要投入大量的时间和金钱。这时,网页封装app就成了一个不错的选择。 app在线封装www,ppzhu.net 什么是…

【AI人工智能】文心智能体,00后疯感工牌生成器,低代码工作流的简单应用以及图片快速响应解决方案,干货满满,不容错过哦

背景 文心智能体平台,开启新一轮活动,超级创造营持续百日活动。 在AI 浪潮席卷的今天,如雨后春笋般丛生的 AI 应用,昭告着时代风口显然已随之到来。 如何能把握住时代红利,占据风口,甚至打造新风向&#x…

探索 Kubernetes 持久化存储之 Longhorn 初窥门径

作者:运维有术星主 在 Kubernetes 生态系统中,持久化存储扮演着至关重要的角色,它是支撑业务应用稳定运行的基石。对于那些选择自建 Kubernetes 集群的运维架构师而言,选择合适的后端持久化存储解决方案是一项至关重要的选型决策。…

因为媳妇的一句话,我做了一个AI画图软件

因为媳妇的一句话,我做了一个AI画图软件 T恤的配图 前些天媳妇参加了一个创业比赛,其中一个比赛任务是参赛成员需要穿主题队服,队服的图案完全需要自己设计,需要独一无二还得漂亮。 问我:“能不能用AI做一张图&#…

Python酷库之旅-第三方库Pandas(052)

目录 一、用法精讲 191、pandas.Series.drop方法 191-1、语法 191-2、参数 191-3、功能 191-4、返回值 191-5、说明 191-6、用法 191-6-1、数据准备 191-6-2、代码示例 191-6-3、结果输出 192、pandas.Series.droplevel方法 192-1、语法 192-2、参数 192-3、功能…

C# 介绍

文章目录 一. 一个简单的helloworld二. 程序结构三. 类型和变量四. 表达式1. f(x)2. []3. typeof4. default5. new6. checked和unchecked7. sizeof8. 移位9. is和as10. null合并 五. 语句六. 类和对象1. 可访问性2. 类型参数3. 基类和派生类4. 字段5. 方法6. 参数7. 扩展方法&a…

53.综合实验:UART接收图像、写入RAM、通过TFT显示

(1)设计定义:UART_RX模块接收数据,通过写入逻辑写入RAM存储器中,然后通过读取逻辑,从RAM中读出数据,发送给TFT显示屏。 (2)FPGA逻辑资源有限,因此设置128 * 1…

新生报到系统2024((代码+论文+ppt)

下载在最后 技术栈: ssmmysqljsp 展示: 下载地址: CSDN现在上传有问题,有兴趣的朋友先收藏.正常了贴上下载地址 备注:

docker安装部署elasticsearch7.15.2

docker安装部署elasticsearch7.15.2 1.拉取es镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:7.15.2如果不想下载或者镜像拉去太慢可以直接下载文章上面的镜像压缩包 使用镜像解压命令 docker load -i elasticsearch-7-15-2.tar如下图所示就表示镜像解压成…

Qt+OpenCascade开发笔记(二):windows开发环境搭建(二):Qt引入occ库,搭建基础工程模板Demo和发布Demo

若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/140763014 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV…

51单片机嵌入式开发:19、STC89C52R控制LCD1602码表+数码管+后台数显(串口)

STC89C52R控制LCD1602码表数码管后台数显(串口) 1 概述1.1 项目概述1.2 项目组成部分1.3 功能描述 2 开发环境2.1 支持设备2.2 硬件电路 3 软件代码工程4 演示4.1 Proteus仿真4.2 实物演示 5 总结 1 概述 1.1 项目概述 本项目旨在利用STC89C52R单片机实…