数据结构 栈
3、栈
栈(Stack)是只允许在一端插入或删除操作的线性表
LIFO(后进先出)
n个不同的元素进栈,出栈的顺序有个,卡特兰(Catalan)数
3.1、顺序栈
栈的定义
#include <stdio.h> #include <stdlib.h> #define MaxSize 10 #define ElemType int #define true 1 #define fales 0 //顺序表定义栈的结构体 typedef struct{ ElemType data[MaxSize]; int top; }SqStack; //初始化一个栈 ElemType InitStack(SqStack *S){ S->top = -1; //栈顶元素指向-1 return true; }
入栈、出栈、读取栈顶元素
//入栈操作 ElemType Push(SqStack *S,ElemType e){ if(S->top == MaxSize-1) return fales; //边界判断 S->data[++S->top] = e; //先栈顶+!,在赋值操作 return true; } //栈顶元素弹出 ElemType Pop(SqStack *S,ElemType *e){ if(S->top == -1) return fales; //栈中没有元素 *e = S->data[S->top--]; //先弹栈在栈顶-1 return true; } //读取栈顶元素 ElemType GetTop(SqStack S,ElemType *e){ if(S.top == -1) return false; //栈中没有元素 *e = S.data[S.top]; return true; }
3.2、链栈
栈的定义
#include <stdio.h> #include <stdlib.h> #define ElemType int #define true 1 #define false 0 //定义一个链栈 typedef struct LinkNode { ElemType data; struct LinkNode *next; } *LinkStack,LinkNode; //初始化一个不带头结点的栈 ElemType InitStack(LinkStack *S){ // *S = (LinkStack)malloc(sizeof(LinkNode)); *S = NULL; return true; } //判断栈是否为空 ElemType Empty(LinkStack S){ if(S == NULL) return false; else true; }
入栈、出栈
//入栈 ElemType Push(LinkStack *S,ElemType e){ LinkNode *p = (LinkNode *)malloc(sizeof(LinkNode)); if(p == NULL) return false; p->data = e; p->next = *S; *S = p; return true; } //弹栈 ElemType Pop(LinkStack *S,ElemType *e){ if(*S == NULL) return false; *e = (*S)->data; (*S) = (*S)->next; return true; }
头插法
3.3、括号匹配
代码
#include <stdio.h> #include <stdlib.h> #define MaxSize 10 #define ElemType char #define true 1 #define false 0 //顺序表定义栈的结构体 typedef struct{ ElemType data[MaxSize]; int top; }SqStack; //判断栈是否为空 int StackEmpty(SqStack S){ if(S.top == -1) return true; else return false; } //初始化一个栈 ElemType InitStack(SqStack *S){ S->top = -1; //栈顶元素指向-1 return true; } //入栈操作 ElemType Push(SqStack *S,ElemType e){ if(S->top == MaxSize-1) return false; //边界判断 S->data[++S->top] = e; //先栈顶+!,在赋值操作 return true; } //栈顶元素弹出 ElemType Pop(SqStack *S,ElemType *e){ if(S->top == -1) return false; //栈中没有元素 *e = S->data[S->top--]; //先弹栈在栈顶-1 return true; } //读取栈顶元素 ElemType GetTop(SqStack S,ElemType *e){ if(S.top == -1) return false; //栈中没有元素 *e = S.data[S.top]; return true; } //括号匹配算法 int bracketCheck(char str[],int length){ SqStack S; //定义栈 InitStack(&S); //初始化栈 for(int i=0;i<length;i++){ if(str[i] == '(' || str[i] == '{' || str[i] == '['){ Push(&S,str[i]); //左括号入栈 }else{ if(StackEmpty(S)) return false; //判断栈是否为空 char topElem; Pop(&S,&topElem); //右括号出栈 if(str[i] == ')' && topElem != '(') return false; if(str[i] == '}' && topElem != '{') return false; if(str[i] == ']' && topElem != '[') return false; } } return StackEmpty(S); } int main(){ char str[] = {'(','(','[',']','{','}',')',')'}; int flag = bracketCheck(str,8); printf("括号是否匹配:%d\n",flag); return 0; } //结果 括号是否匹配:1
3.4、表达式求值问题
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)