栈和队列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.hqwc.cn/news/97572.html

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

相关文章

音频修复和增强工具 iZotope RX 10 for mac激活最新

iZotope RX 10是一款音频修复和增强软件,主要特点包括: 声音修复:iZotope RX 10可以去除不良噪音、杂音、吱吱声等,使音频变得更加清晰干净。音频增强:iZotope RX 10支持对音频进行音量调节、均衡器、压缩器、限制器等…

Spring框架中如何处理事务管理

文章目录 **1. 声明式事务管理:****定义事务管理器:****配置事务通知:****将事务通知应用到方法:** **2. 编程式事务管理:****通过编程方式启动事务:** **3. 配置事务属性:** 🎈个人…

【2023集创赛】加速科技杯二等奖作品:基于ATE的电源芯片测试设计与性能分析

本文为2023年第七届全国大学生集成电路创新创业大赛(“集创赛”)加速科技杯二等奖作品分享,参加极术社区的【有奖征集】分享你的2023集创赛作品,秀出作品风采,分享2023集创赛作品扩大影响力,更有丰富电子礼…

DES和3DES等常见加解密的关键要素---安全行业基础篇3

DES和3DES DES和3DES是对称加密算法,其加密和解密的关键要素包括: 密钥:DES和3DES使用相同长度的密钥进行加密和解密。DES使用56位密钥,而3DES可以使用112位或168位密钥。密钥是保护数据安全的关键,必须保持机密并只…

SQLite简单介绍

一.简单介绍 SQLite是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的,而且已经在很多嵌入式产品中使用了它,它占用资源非常的低&…

【django开发手册】详解drf filter中DjangoFilterBackend,SearchFilter,OrderingFilter使用方式

💖 作者简介:大家好,我是Zeeland,开源建设者与全栈领域优质创作者。📝 CSDN主页:Zeeland🔥📣 我的博客:Zeeland📚 Github主页: Undertone0809 (Zeeland)&…

uniapp集成windicss的流程

一、背景介绍 Windicss是一个基于Tailwind CSS 灵感的库,它更快、更兼容,使用 TypeScript 构建。Windicss的目标是为了解决与Tailwind CSS 类似的问题,提供一个可以快速上手开发的组件库,让开发者不再需要繁琐地编写 CSS 样式。Windicss包含了几乎所有的 CSS 样式,因此开发…

大数据课程K20——Spark的SparkSql概述

文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解Spark的SparkSQL由来; ⚪ 了解Spark的SparkSQL特点; ⚪ 了解Spark的SparkSQL优势; ⚪ 掌握Spark的SparkSQL入门; 一、SparkSQL概述 1. 概述 Spark为结构化数据处理引入了一个称…

Unity设置TextMeshPro文本超出范围显示...

TextMtshPro文本超出范围,展示省略。选择Overflow为Ellipsis。

高忆管理:总市值和流动市值区别?

总市值和活动市值是衡量一个公司或许财物商场价值的两个常用指标。总市值是指一个公司的悉数股票乘以当时股价的总值,而活动市值则是指一个公司的可自在买卖的股票乘以当时股价的总值。总市值和活动市值之间有着很大的不同,下面从多个角度进行分析。 首…

连接云-边-端,构建火山引擎边缘云网技术体系

近日,火山引擎边缘云网络产品研发负责人韩伟在LiveVideoStack Con 2023上海站围绕边缘云海量分布式节点和上百T的网络规模,结合边缘云快速发展期间遇到的各种问题和挑战,分享了火山引擎边缘云网的全球基础设施,融合开放的云网技术…

spacy安装旧版本en_core_web_sm的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…