首先我们来看一下什么是栈的定义与相关概念:
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶。
1.从图中可以看出,我们一般用数组来实现栈。
2.先进入栈的值后弹出,后进入栈的值先弹出。如同弹夹一般,先被压入弹夹的子弹最后发射,而最后被压入弹夹的子弹最先发射。
OK,接下查看接口
#include <stdio.h>
#include <stdlib.h>//调用动态内存开辟的相关函数
#include <stdbool.h>//引入bool 类型
#include <assert.h>//通过断言,方便调试阶段处理错误
typedef int StackDataType; //定义栈中值的类型,方便后期的维护
typedef struct Stack Stack; //将栈的结构体类型名变为稍微简单的类型名,方便
//后续使用
struct Stack //定义栈的结构体
{
StackDataType* a; //指针a 来维护对应的栈
int top;//栈顶的位置
int capacity;//容量大小
};
void StackInit(Stack* ps); //初始化栈
void StackDestory(Stack* ps);//销毁栈
void StackPush(Stack* ps,StackDataType x); //把值压入栈
void StackPop(Stack* ps); //把值弹出栈
bool StackEmpty(Stack* ps); // 查看栈是否为空,如果为空不再弹出值
int StackSize(Stack* ps); //查看栈中有效值的个数
StackDataType StackTop(Stack* ps); //查看栈顶的值
第一部分:栈的初始化和销毁
void StackInit(Stack* ps)
{
assert(ps); //断言栈的结构体指针是否为空
ps->a = NULL; //置空维护栈的指针
ps->top = ps->capacity = 0;//将栈中有效值个数和栈的容量置为0
}
void StackDestory(Stack* ps)
{
assert(ps);
free(ps->a); //
ps->a = NULL; // 释放维护栈的指针并将其置空
ps->top = ps->capacity = 0;//将栈中有效值个数和栈的容量置为0
}
第二部分:栈中有效值的压入与弹出
void StackPush(Stack* ps, StackDataType x)
{
assert(ps);
//满了扩容
if (ps->top == ps->capacity) //当栈中有效值的个数与其容量相等,说明需要扩容
{
//首次使用栈的容量是0,故而我们需要将其变为4(只要不是0都可以)
//非首次使用,如果栈满了只需将容量扩为原来的二倍即可
int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
//用临时的指针变量来存放realloc的返回值
//防止realloc开辟内存失败,导致原来的有效数值缺失
StackDataType* tmp = (StackDataType*)realloc(ps->a, newCapacity*sizeof(StackDataType));
if (tmp == NULL)//检查动态内存开辟是否失败
{
printf("realloc fail\n");
exit(-1);
}
ps->a = tmp;//如果开辟成功,交给原来维护栈的指针
ps->capacity = newCapacity;//更新容量
}
ps->a[ps->top] = x;//压入有效数据
ps->top++;//增加栈中有效数据个数
}
void StackPop(Stack* ps)
{
assert(ps);
assert(ps->top > 0);//栈为空,不弹出
ps->top--; //栈不为空,弹出
}
第三部分:检验栈是否为空;查看栈中有效值的个数;查看栈顶的值
bool StackEmpty(Stack* ps)//使用bool类型的返回值
{
assert(ps);
return ps->top == 0; //检验有效值的个数是否为0
}
int StackSize(Stack* ps)
{
assert(ps);
return ps->top; //直接返回有效值个数
}
StackDataType StackTop(Stack* ps)//返回值类型为栈有效值的类型
{
assert(ps);
return ps->a[ps->top - 1];//top-1 对应栈顶元素的下标
}
好啦,本篇博客分享到此为止,如果内容有错误还请在评论区指正。希望看完本篇博客有所收获的小伙伴能够点赞和转发。后续也会带来更多干货!