栈概念
栈的特点:
先进后出
栈的优:
栈是在数组中存储的 支持随机访问
栈的结构
使用 栈使用顺序表实现的
a指向动态开辟的一块空间(用来存放数据) top有效数据个数(要插入数据的下标)capciaty 空间容量
typedef int SKDataType;
typedef struct StackNode
{
SKDataType* a;
int top; //要插入数据的下标
int capacity; //有效的空间大小
}Stack;
栈 的初始化
初始化 可以给一块空间 也可以不给 空间 (这里已不给 空间例子)
top 初始化 为0 (top-1)就是栈顶的元素的下标 top 有效的数据个数
top 初始化 为-1 浪费一个变量 从下标1 开始存储第一个有效数据 top 为栈顶元素的下标
void StackInit(Stack* sk)
{
sk->a = NULL;
sk->top = 0;
sk->capacity = 0;
}
栈 的 插入
因为栈 数据结构的特点 只允许在 一端进行插入 删除
所以 扩容不需要函数封装插入的时候需要检查下 空间够用不
void StackPush(Stack* sk, SKDataType x)
{
if (sk->top == sk->capacity)
{
int NewCapacity = sk->capacity == 0 ? 6 : sk->capacity * 2;
// sk->a 为空 realloc 作用 和 malloc 一样
SKDataType* tmp = realloc(sk->a, sizeof(SKDataType) * NewCapacity);
if (tmp == NULL)
{
perror("realloc:");
exit(-1);
}
//扩容两种 原地扩容 异地扩容
//为了防止异地扩容 tmp赋值给sk->a
sk->a = tmp;
sk->capacity = NewCapacity;
}
//在top 位置插入
sk->a[sk->top] = x;
//再++ top top指向当前插入元素的下一个
sk->top++;
}
栈 的删除
栈 的 删除
top 是 当前元素的下一个 (top-1) 下一个插入的元素会把之前的元素覆盖 就是没有下一个元素 也 没事
因为栈存储再数组中 数组是通过下标访问的(top-1)栈的有效元素个数(-1)除非数组越界 否则是不可能访问下(top-1)的
再 Pop 栈 时 栈 不为空 top表示有效元素个数 top不等于0
void StackPop(Stack* sk)
{
assert(sk);
assert(sk->top > 0);
sk->top--;
}
获取栈顶部的元素
top 是指向当前元素的下一个(top-1)的下标 栈顶部第一个有效元素
如果 top 等于0 说明里面没元素,那自然不会有顶部的元素
SKDataType StackTop(Stack* sk)
{
assert(sk);
assert(sk->top > 0);
return sk->a[sk->top-1];
}
获取栈有效元素个数
top 表示有效元素个数
int StackSize(Stack* sk)
{
return sk->top;
}
判断栈是否为空
top == 0 判断是否为空的条件
bool StackEmpty(Stack* sk)
{
return sk->top == 0;
}
栈 的销毁
释放动态开辟申请的空间 把a 置空 清理top 和capacity
void StackDestory(Stack* sk)
{
free(sk->a); //释放动态申请的空间
sk->a = NULL; //置空
sk->top = sk->capacity = 0; //清0
}
总结
以上就是本文要介绍的所有内容,如果觉得有帮助可以给个三连哦🌹🌹🌹