C实现栈及OJ题有效的括号
创始人
2025-05-30 12:46:26
0

文章目录

  • 栈概念及基本操作
  • 源码
  • OJ题括号匹配


栈概念及基本操作

栈也同链表和顺序表一样是一种线性表只是比较特殊而已,栈遵循一种先进后出的原则,其实栈就像生活中的叠盘子一样,将盘子一个一个的叠起来,每次都只能在最顶层叠,然后取盘子的时候也是从顶层一个一个的拿;
在这里插入图片描述

就同上面盘子一样,最先放的那个盘子它所在的位置是最底下的,然后最后放的那个盘子所在的位置在最上面。其实转到栈来说最早进入栈的那个元素存放的位置被称为栈底,最后进入的那个元素存放的位置被称为栈顶,但是并不是最先进栈的元素要最后才出,它最先进去的也可以最先出栈只是它进栈然后再出栈才将后一个元素进栈。

我们每次对栈的操作包括:插入数据(进栈)、删除数据(出栈)都是在栈顶进行的。
那应该用什么来实现?它既可以用数组实现也可以用数组实现,但是这里用数组实现要稍好,因为数组每次都在尾端进行插入删除操作,以数组实现栈操作,出栈和入栈在尾部操作,不会移动额外的元素,它的时间复杂度为O(1),它有一个唯一的缺陷就是空间不够了需要扩容,但是内存申请是特别快,而且他也不是每次都需要扩容。但是如果一定要用链表的话,那么用单向还是双向链表,这里用单向链表较好,因为双向链表毕竟还要多用一个指针,所以用单链表吧,那么单链表的话就以栈顶为单链表的头,链表每次在头进行插入和删除操作,即时间复杂度也为O(1),但是栈用链表实现还是数组实现,这里看个人习惯叭,我还是比较习惯用数组实现,本文就是以数组来实现栈的。

栈的结构定义

typedef int SLDataType;//这里为栈类型,以后类型修改的时候就可以在这里进行修改不然的话在代码中去要修改很多麻烦
typedef struct Stack
{SLDataType* a;//动态栈int top;//栈顶int capacity;//初始容量大小一般情况下先给4个元素大小
}St;

当然也可以用静态数组实现,只是空间不好把握

对于top的初始化给值可以有很多种,但是一般是0,或者-1,给0,代表top位置为栈顶元素的下一个位置,用的时候先用再加加,然后top给-1的话表示当前位置就是栈顶元素的位置,用的时候先加加再使用
在本文中top为0
栈的初始化

开始时op = 0,并且给栈先分配四个元素大小空间

void STInit(St* s)
{//初始化栈大小为4s->a = malloc(sizeof(SLDataType) * 4);if (s->a == NULL){perror("malloc fail\n");return;}s->capacity = 4;//s->top = 0;
}

压栈

void STPush(St* s, SLDataType x)
{assert(s);if (s->top == s->capacity)//判断栈是否满//栈这时满了,那么就要扩容了,扩容一般情况下扩二倍{SLDataType* tmp = (SLDataType*)realloc(s->a, sizeof(SLDataType)*(s->capacity)* 2);if (tmp == NULL){perror("realloc fail\n");return;}else{s->a = tmp;s->capacity *= 2;}}s->a[s->top] = x;s->top++;
}

出栈

//这里出栈是将栈顶元素删掉,
void STPop(St* s)
{assert(s);assert(s->top>0);//断言判断,栈为空就直接报错//这里判断栈是否为空s->top--;
}

取栈顶元素

int STTop(St* s)
{assert(s->top>0);return s->a[(s->top-1)];//直接返回栈顶的那个元素,但是要注意的是栈顶下标,top表示的是栈顶元素的下一个位置,所以这里top要减一才可以取到栈顶元素
}

栈大小

int STSize(St* s)
{return s->top;//栈顶指针top所在位置就是栈中有效元素的个数
}

销毁

void STDestroy(St* s)
{assert(s);free(s->a);//动态开辟的释放,不然存在内存泄漏危机s->a = NULL;s->top = 0;s->capacity = 0;
}

源码

stack.c

#include"Stack.h"void STInit(St* s)
{assert(s);//初始化栈大小为4s->a = malloc(sizeof(SLDataType) * 4);if (s->a == NULL){perror("malloc fail\n");return;}s->capacity = 4;s->top = 0;
}
//
//销毁栈
void STDestroy(St* s)
{assert(s);free(s->a);s->a = NULL;s->top = 0;s->capacity = 0;
}//插入x,尾插(栈顶插入)
void STPush(St* s, SLDataType x)
{assert(s);if (s->top == s->capacity){SLDataType* tmp = (SLDataType*)realloc(s->a, sizeof(SLDataType)*(s->capacity)* 2);if (tmp == NULL){perror("realloc fail\n");return;}else{s->a = tmp;s->capacity *= 2;}}s->a[s->top] = x;s->top++;
}//出栈
void STPop(St* s)
{assert(s);assert(s->top>0);s->top--;
}//判空
bool STEmpty(St*s)
{assert(s);return s->top == 0;}//栈顶元素
int STTop(St* s)
{assert(s);assert(s->top>0)return s->a[(s->top-1)];
}//栈的大小
int STSize(St* s)
{	assert(s);return s->top;
}

Stack.h


#include
#include
#include
#includetypedef int SLDataType;
typedef struct Stack
{int* a;int top;int capacity;
}St;//初始化栈
void STInit(St* s);//销毁栈
void STDestroy(St* s);//入栈(压栈)
void STPush(St* s, SLDataType x);//取栈顶元素
int STTop(St* s);//判断栈是否为空
bool STEmpty(St*s);//出栈
void STPop(St* s);//栈大小
int STSize(St* s);

test.c

栈实现
#include"Stack.h"void test()
{St st;STInit(&st);STPush(&st, 1);STPush(&st, 2);STPush(&st, 3);STPush(&st, 4);while (!STEmpty(&st)){printf("%d ", STTop(&st));STPop(&st);}//STDestroy(&st);
}
int main()
{test();return 0;
}

OJ题括号匹配

下面来看这样一个OJ题
在这里插入图片描述

给定字符串且只含括号,问字符串是否有效,其实就是检查它们是否匹配,这里匹配可是要按顺序匹配啊,如 ( 只能 由 ) 与其匹配,{ 只能由
} 与其匹配 , [ 只能由 ] 与其匹配,不能出现混淆,如果不按这样顺序匹配也是无效的
查看是否匹配我们就可以用栈来实现,当左括号就进栈,然后右括号就取出栈顶元素与当前字符比较是否匹配,
用我们刚刚写的栈作为接口来实现这道OJ题

typedef char STDataType;//由于是字符串,所以自需要在这里更改类型就可以了
typedef struct STNode
{STDataType* a;int top;int capacity;
}ST;
void StackInit(ST* st)
{assert(st);st->a = (STDataType*)malloc(sizeof(STDataType)*4);if (st->a == NULL){printf("malloc fail\n");exit(-1);}st->capacity = 4;st->top = 0;
}
//销毁
void StackDestory(ST* st)
{assert(st);free(st->a);st->a = NULL;st->top = st->capacity = 0;
}
//进栈
void StackPush(ST* st, STDataType x)
{assert(st);if (st->top == st->capacity){STDataType* tmp = (STDataType*)realloc(st->a,st->capacity*2*(sizeof(STDataType) ));if (tmp == NULL){printf("realloc fail\n");exit(-1);}else{st->a = tmp;st->capacity *= 2;}}st->a[st->top] = x;st->top++;
}
//出栈
void StackPop(ST* st)
{assert(st);assert(st->top > 0);st->top--;
}
//判空
bool StackEmpty(ST* st)
{assert(st);return st->top == 0;
}
//获取栈顶元素
STDataType StackTop(ST* st)
{assert(st);assert(st->top > 0);return st->a[st->top-1];
}
//获取栈的大小
int StackSize(ST* st)
{assert(st);return st->top;
}
//先将栈的这些接口写上//左括号就进栈
// 右括号就将取栈顶元素与当前字符比较是否匹配
// 注意:判断栈空
// 如果栈一开始就是空的,且当前字符为右括号,那么就是不匹配
// (){}[]这种匹配形式
// 且还需要注意字符串已经匹配完了,但是栈里面还是有元素时,也是不匹配的
bool isValid(char * s)
{ST st;StackInit(&st);while(*s != '\0'){//当前字符为左括号进进栈if(*s == '(' ||*s =='{' || *s == '['){StackPush(&st,*s);}//右括号就取栈顶元素匹配且出栈else{//在匹配时要确保有左括号和当前右括号匹配,就要保证栈不为空if(!StackEmpty(&st)){ //在栈不为空的情况下取出栈顶元素与当前字符匹配,看是否能匹配成功,匹配成功就将栈顶元素出栈然后字符串向后走继续匹配char c = StackTop(&st);if(c =='(' && *s==')' || c=='[' &&*s ==']' || c =='{' && *s=='}')StackPop(&st);else{return false;}}else{return false;}}  s++;}//最后字符串结束之后检查栈是否为空,为空就表示所有都是匹配的,返回true,不为空就表示里面还有左括号没有参与匹配,就是匹配失败,返回falseif(!StackEmpty(&st)){return false;}elsereturn true;
}

栈的应用有很多,著名的有对于历史的回溯,如网页的打开,用户打开了许多网页,然后用户可以很快的回到上以个浏览页面甚至更上一个页面。但是今天关于栈的实现就到这里叭

相关内容

热门资讯

阿联酋最大银行及另两家中东银行... 观点网讯:5月8日,路透社报道指,阿联酋最大银行第一阿布扎比银行(First Abu Dhabi B...
深圳239亿地王易主,再造万象... 2017年,世茂集团豪掷239.43亿元拿下世茂深港国际中心地块,曾规划建筑高度达700米的深圳第一...
蔚来在安庆成立新能源科技公司 ... 天眼查App显示,近日,安庆蔚来新能源科技有限公司成立,法定代表人为姚蒀,注册资本500万人民币,经...
美国牛肉商期盼峰会重启对华出口 据路透社5月8日报道,美国牛肉生产商正期待特朗普与中国于5月14日至15日的峰会推动对华出口许可恢复...
创业板首家未盈利企业,市值突破... 5月8日,大普微总市值正式突破2000亿元大关。截至午间收盘,大普微涨14.07%,报493.1元/...
招商证券:董事长霍达因工作变动... 招商证券公告,公司董事长霍达因工作变动申请辞去董事长、执行董事等全部职务,辞任自辞呈送达董事会之日生...
原创 中... 【阅读须知】本文所引用的所有信息和数据,均为作者通过查阅官方资料与网络公开数据整理、分析而成,旨在为...
原创 从... 2026年5月5日,中国商务部发布了一项具有划时代意义的专项阻断禁令,这份公告让一向倚仗长臂管辖的美...
布米普特拉北京投资基金管理有限... 美国圣路易斯联邦储备银行总裁穆萨莱姆周三发出明确信号,美联储货币政策面临的潜在风险正在发生关键转向。...
加工的秘密:超精加工设备如何做... 你知道吗? 一根头发丝的直径大约0.07毫米,也就是70微米。 超精加工设备,可切出表面,其尺寸为0...
招商证券董事长霍达因工作变动离... 北京商报讯(记者 刘宇阳 实习生 王思奕)5月8日,招商证券发布关于公司董事长离任暨推举董事代行董事...
华帝股份营收创近3年新低,37... 乐居财经李兰近日,华帝股份(002035.SZ)发布2025年年度报告。 2025年,华帝股份实现营...
大模型融资杀疯了!月之暗面狂揽... 图源:视觉中国 5月7日,据华峰资本官微消息,国内头部大模型公司月之暗面(Kimi)于近日完成新一轮...
扎根长宁二十余载,仲利国际融资... 作为总部扎根上海长宁的优质台资金融企业,仲利国际融资租赁有限公司深耕融资租赁行业二十余载,始终坚守金...
估值210亿!李彦宏又将收获一... 来源:直通IPO,文/王非 国产GPU上市潮仍然汹涌,继两家登陆A股、两家登陆H股后,这家公司正推进...
基金“盲盒”拆了 公募基金正在迎来一场让投资者“看得懂”的变革。 近日,华夏、易方达、南方、招商等12家头部及特色基金...
原创 2... 前言 十年间,中国企业在印尼镍产业链累计砸下超过140亿美元,电厂、公路、码头和全套生产线,硬生生...
原创 欧... 俄罗斯卫星通讯社5月6日报道,欧盟宣布禁止欧洲银行为含有来自不可靠供应商的关键部件的可再生能源项目提...
原创 余... 2026年5月2日,在中国理财市场扎根十三年的余额宝,终于触碰到了一个让所有人错愕的数字——7日年化...
银华基金增聘谭普景共同管理银华... 来源:新浪基金∞工作室 5月8日,银华基金管理股份有限公司发布公告称,为银华中证机器人交易型开放式指...