数据结构-栈
Posted Fly-bit
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构-栈相关的知识,希望对你有一定的参考价值。
目录
前言
本文均基于C语言实现。
以下是本篇文章正文内容,下面案例可供参考
一、栈的概念与结构
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为 栈顶,另一端称为 栈底。栈中的数据元素遵守 后进先出 LIFO(Last In First Out)的原则。
入栈 :栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈 :栈的删除操作叫做出栈。出数据也在栈顶。
二、C语言-栈的基本操作与实现
栈的基本操作主要有以下几点:初始化、入栈、出栈、获取栈顶元素、获取栈中有效元素个数、判空、销毁栈
1.栈的创建
栈和线性表类似,也有两种存储表示方法:定长的 静态栈 和支持动态增长的 链栈,链栈的操作是线性表操作的特例,操作比较容易实现。静态栈,即栈的顺序存储结构是利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针 top 指示栈顶元素在顺序栈中的位置, top = 0 表示空栈,因此, 非空栈中,top 表示栈顶元素的下一个位置。由于其在实际中并不实用,故下面所实现均为 动态增长的栈
另附静态栈:
#define N 10
typedef struct Stack
{
STDataType arr[N];
int top; // 栈顶
}Stack;
支持动态增长的栈 :
// 支持动态增长的栈
typedef int STDataType; //方便修改不同栈数据类型
typedef struct Stack
{
STDataType* a;
int top; // 栈顶
int capacity; // 容量
}Stack;
2.栈的初始化
此处 top = 0 表示空栈,方便后期判断栈是否为满。 非空栈中,top 表示栈顶元素的下一个位置。
代码如下:
// 初始化栈
void StackInint(Stack* ps)
{
assert(ps);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
3.入栈
判断栈是否为满,若满,则使用 realloc() 函数另外开辟空间。若有小伙伴忘记该函数,记得下去复习!
代码如下:
void StackPush(Stack* ps, STDataType data)
{
if (ps->top == ps->capacity) //判断是否需要扩容
{
int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newcapacity);
if (tmp == NULL)
{
printf("realloc failed\\n");
exit(-1);
}
ps->a = tmp;
ps->capacity = newcapacity;
}
ps->a[ps->top] = data;
ps->top++;
}
4.出栈
此处须判断栈是否为 空 ,倘若为空,出栈后 top = -1 ,入栈时会导致非法访问内存。
代码如下:
void StackPop(Stack* ps)
{
assert(ps);
assert(!StachEmpty(ps)); //判断不为空
ps->top--;
}
5.获取栈顶元素
此处判断栈是否为 空 ,倘若为空,即空栈,无数据。
代码如下:
STDataType StackTop(Stack* ps)
{
assert(ps);
assert(!StachEmpty(ps));
return ps->a[ps->top - 1];
}
6.获取栈中有效元素个数
代码如下:
int StackSize(Stack* ps)
{
assert(ps);
return ps->top;
}
7.检测栈是否为空
若空返回非0结果,否则返回0
代码如下:
bool StachEmpty(Stack* ps)
{
assert(ps);
if (ps->top == 0)
return true;
return false;
}
8.销毁栈
释放 realloc() 所开辟的空间,将 a 置为 NULL ,保持良好习惯
代码如下:
void StackDestroy(Stack* ps)
{
assert(ps);
if (ps->a)
free(ps->a);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
三、栈的经典使用
1.问题叙述
附上链接 : 括号匹配问题
题目描述如下:
2.解题方法
解题思路:本题可以使用 栈 这一数据结构来解决。
我们遍历给定的字符串 s。当我们遇到一个左括号时,我们会期望在后续的遍历中,有一个相同类型的右括号将其闭合。因此结合示例可以看出,每每遇到 左括号,进行 入栈操作,遇到 右括号,进行 出栈操作,与之匹配,若不匹配,返回 false.当字符串遍历完,且栈为空,即返回 true
复杂度分析:
时间复杂度:O(N) 即遍历了一遍字符串。
空间复杂度:O(N) 假如输入是 [[[[[[[[[ ,栈的大小将是输入字符串的长度。
3.代码实现
由于上面已经创建好 栈 ,代码直接拿来使用(是的,ctrl + c 和 ctrl + v 是一个“合格程序员”的“基本修养”)
bool isValid(char * s){
//栈的实现
typedef struct Stack
{
char* a;
int top;
int capacity;
}Stack;
void StackInint(Stack* ps)
{
assert(ps);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
bool StackEmpty(Stack* ps)
{
assert(ps);
if (ps->top == 0)
return true;
return false;
}
void StackDestroy(Stack* ps)
{
assert(ps);
if (ps->a)
free(ps->a);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
void StackPush(Stack* ps, char data)
{
if (ps->top == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
char* tmp = (char*)realloc(ps->a, sizeof(char) * newcapacity);
if (tmp == NULL)
{
printf("realloc failed\\n");
exit(-1);
}
ps->a = tmp;
ps->capacity = newcapacity;
}
ps->a[ps->top] = data;
ps->top++;
}
char StackTop(Stack* ps)
{
assert(ps);
if(ps->top)
return ps->a[ps->top - 1];
return 'a';
}
void StackPop(Stack* ps)
{
assert(ps);
assert(!StackEmpty(ps));
//free(ps->a + ps->top - 1);
ps->top--;
}
int StackSize(Stack* ps)
{
assert(ps);
return ps->top;
}
Stack ST;
StackInint(&ST);
//进行括号匹配
while(*s)
{
//为左括号,入栈
if((*s == '(')||(*s == '[')||(*s == '{'))
StackPush(&ST, *s);
else
{
//右括号,与栈顶元素匹配,匹配成功则出栈,反之返回 false
if((*s==')'&&StackTop(&ST)!='(')
||(*s==']'&&StackTop(&ST)!='[')||
(*s=='}'&&StackTop(&ST)!='{'))
return false;
StackPop(&ST);
}
s++;
}
if(StackEmpty(&ST)!=0)
return true;
return false;
}
附上运行图 :
以上就是本次用c语言所带来的内容,如为你带来帮助,点赞支持一波吧
以上是关于数据结构-栈的主要内容,如果未能解决你的问题,请参考以下文章