1、栈的概念及结构
栈(Stack):是只允许在一端进行插入或删除的线性表。首先栈是一种线性表,但限定这种线性表只能在某一端进行插入和删除操作。
栈顶(Top):线性表允许进行插入删除的那一端。
栈底(Bottom):固定的,不允许进行插入和删除的另一端。
空栈:不含任何元素的空表。
栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构
2、栈的实现
创建栈
首先,我们需要用结构体创建一个栈,这个结构体需要包括栈的基本内容(栈,栈顶,栈的容量)。
typedef int STDataType;//栈中存储的元素类型(这里用整型举例)
typedef struct Stack
{
int* _a;//带_是指结构体成员,这里我们前面带_
int* _top;//栈顶
int _capacity;//容量
}Stack;
实现接口
void StackInit(Stack* pst);//初始化
void StackDestory(Stack* pst);//销毁
void StackPush(Stack* pst);//入栈
void StackPop(Stack* pst);//出栈
void StackSize(Stack* pst);//获取栈个数
int StackEmpty(Stack* pst);//返回1是空,返回零是非空
STDataType StackTop(Stack* pst);//获取栈顶的数据
初始化栈
void StackInit(Stack* pst)//初始化
{
assert(pst);
pst->_a = (STDataType*)malloc(sizeof(STDataType) * 4);
pst->_top = 0;
pst->_capacity = 4;
}
销毁栈
因为栈的内存空间是动态开辟出来的,当我们使用完后必须释放其内存空间,避免内存泄漏。
void StackDestory(Stack* pst)//销毁
{
assert(pst);
free(pst->_a);//释放栈
pst->_a = NULL;//即使置空
pst->_top = pst->_capacity = 0;//栈顶和容量置为0
}
入栈
进行入栈操作前,我们需要检测栈的当前状态,若已满,则需要先对其进行增容,然后才能进行入栈操作。
void StackPush(Stack* pst)//入栈
{
assert(pst);
if (pst->_top == pst->_capacity)
{
pst->_capacity *= 2;
STDataType* tmp = (STDataType*)realloc(pst->_a, sizeof(STDataType) * pst->_capacity * 2);
if (tmp == NULL)
{
printf("内存不足\n");
exit(-1);
}
else
{
pst->_a = tmp;
}
}
}
出栈
出栈操作比较简单,即让栈顶的位置向下移动一位即可。但需检测栈是否为空,若为空,则不能进行出栈操作。
void StackPop(Stack* pst)//出栈
{
assert(pst);
assert(pst->_top > 0);
--pst->_top;
}
获取栈中有效元素个数
因为top记录的是栈顶,使用top的值便代表栈中有效元素的个数。
void StackSize(Stack* pst)//获取栈个数
{
assert(pst);
return pst->_top;
}
检查是否为空
检测栈是否为空,即判断栈顶的位置是否是0即可。若栈顶是0,则栈为空。
int StackEmpty(Stack* pst)//返回1是空,返回零是非空
{
assert(pst);
return pst->_top == 0 ? 1 : 0;
}
获取栈顶元素
获取栈顶元素,即获取栈的最上方的元素。若栈为空,则不能获取。
STDataType StackTop(Stack* pst)//获取栈顶的数据
{
assert(pst);
assert(pst->_top > 0);
return pst->_a[pst->_top - 1];
}