栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。 出栈:栈的删除操作叫做出栈。出数据也在栈顶。

栈底层结构选型
栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。
我们选择数组而不是链表有如下的几点优势:
1. 访问效率更高
int stack[100]; ,要获取栈顶元素(假设栈顶元素下标为 top ),直接使用 stack[top] 就能获取到。2. 空间利用率更优
int stack[100]; ,它会连续占用 100 个 int 类型大小的内存空间,不会有其他额外空间。int 类型的数据外,还需要一个指针来指向下一个节点,这就导致同样存储 n 个整数,链表占用的内存空间比数组更多。3. 实现简单
stack[++top] = element; ,出栈操作代码可以是 int popped = stack[top--]; 。4. 缓存友好
#define _CRT_SECURE_NO_WARNINGS
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
//定义栈的结构
typedef int STDataType;
typedef struct Stack {
STDataType* arr;//数组
int top;//指向栈顶的位置 -- 刚好就是栈中有效数据个数
int capacity;//栈的空间大小
}ST;
//栈的初始化
void STInit(ST* ps);
//栈的销毁
void STDesTroy(ST* ps);
//入栈 -- 栈顶
void STPush(ST* ps, STDataType x);
//判断栈是否为空
bool STEmpty(ST* ps);
//出栈 -- 栈顶
//栈不能为空
void STPop(ST* ps);
//取栈顶元素
STDataType STTop(ST* ps);
//获取栈中有效元素个数
int STSize(ST* ps);#include"Stack.h"
//栈的初始化
void STInit(ST* ps)
{
ps->arr = NULL;
ps->top = ps->capacity = 0;
}
//栈的销毁
void STDesTroy(ST* ps)
{
if (ps->arr)
free(ps->arr);
ps->arr = NULL;
ps->top = ps->capacity = 0;
}
//入栈 -- 栈顶
void STPush(ST* ps, STDataType x)
{
assert(ps);
//判断空间是否足够
if (ps->top == ps->capacity)
{
//增容
int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
STDataType* tmp = (STDataType*)realloc(ps->arr, newCapacity * sizeof(STDataType));
if (tmp == NULL)
{
perror("realloc fail!");
exit(1);
}
ps->arr = tmp;
ps->capacity = newCapacity;
}
//空间足够
ps->arr[ps->top] = x;
ps->top++;
}
//判断栈是否为空
bool STEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
//出栈 -- 栈顶
void STPop(ST* ps)
{
assert(!STEmpty(ps));
//栈不为空
ps->top--;
}
//取栈顶元素
STDataType STTop(ST* ps)
{
//栈不能为空,否则取不了
assert(!STEmpty(ps));
return ps->arr[ps->top - 1];
}
//获取栈中有效元素个数
int STSize(ST* ps)
{
assert(ps);
return ps->top;
}#include"Stack.h"
void test01()
{
ST st;
STInit(&st);
STPush(&st, 1);
STPush(&st, 2);
STPush(&st, 3);
STPush(&st, 4);
//STPop(&st);
//循环出栈并且打印出栈元素
while (!STEmpty(&st))
{
//取栈顶
STDataType top = STTop(&st);
printf("%d ", top);
//出栈
STPop(&st);
}
printf("\n");
printf("size:%d\n", STSize(&st));
STDesTroy(&st);
}
int main()
{
test01();
return 0;
}https://leetcode.cn/problems/valid-parentheses/description/

先将左括号全部入栈然后用指针pi去遍历右括号与栈顶元素比较,看看是否匹配,匹配成功就出栈,如果最后栈为空就返回true,否则就返回false
时间复杂度:O(N)
//定义栈的结构
typedef char STDataType;
typedef struct Stack {
STDataType* arr;//数组
int top;//指向栈顶的位置 -- 刚好就是栈中有效数据个数
int capacity;//栈的空间大小
}ST;
//栈的初始化
void STInit(ST* ps)
{
ps->arr = NULL;
ps->top = ps->capacity = 0;
}
//栈的销毁
void STDesTroy(ST* ps)
{
if (ps->arr)
free(ps->arr);
ps->arr = NULL;
ps->top = ps->capacity = 0;
}
//入栈 -- 栈顶
void STPush(ST* ps, STDataType x)
{
assert(ps);
//判断空间是否足够
if (ps->top == ps->capacity)
{
//增容
int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
STDataType* tmp = (STDataType*)realloc(ps->arr, newCapacity * sizeof(STDataType));
if (tmp == NULL)
{
perror("realloc fail!");
exit(1);
}
ps->arr = tmp;
ps->capacity = newCapacity;
}
//空间足够
ps->arr[ps->top] = x;
ps->top++;
}
//判断栈是否为空
bool STEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
//出栈 -- 栈顶
void STPop(ST* ps)
{
assert(!STEmpty(ps));
//栈不为空
ps->top--;
}
//取栈顶元素
STDataType STTop(ST* ps)
{
//栈不能为空,否则取不了
assert(!STEmpty(ps));
return ps->arr[ps->top - 1];
}
//获取栈中有效元素个数
int STSize(ST* ps)
{
assert(ps);
return ps->top;
}
//-------以上就栈结构的定义和常见方法-------
bool isValid(char* s) {
//借助数据结构 -- 栈
ST st;
STInit(&st);
char *pi=s;//s就是指向字符串的第一个字符
while(*pi != '\0')
{
//左括号入栈
if(*pi == '(' || *pi == '[' || *pi =='{')
{
STPush(&st,*pi);
}
else
{
//右括号 -- 取栈顶,比较,匹配则出栈,不匹配直接返回false
//栈不为空才能取栈顶
if(STEmpty(&st))
{
STDesTroy(&st);
return false;
}
char top = STTop(&st);
if((top == '(' && *pi != ')')
||(top == '[' && *pi != ']')
||(top == '{' && *pi != '}'))
{
STDesTroy(&st);
return false;
}
//本次是匹配的 -- 出栈
STPop(&st);
}
pi++;
}
//判断栈是否为空,为空有效,非空无效
if(STEmpty(&st))
{
STDesTroy(&st);
return true;
}
STDesTroy(&st);
return false;
//也可以简写成如下:
//bool ret = STEmpty(&st) ? true :false
//STDesTroy(&st);
//return ret;
}