文章目录
栈的概念
栈是一种特殊的线性表,只允许在固定的一段进行插入删除操作。
进行数据插入删除的一端叫做栈顶,另一端叫做栈底。
栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶。
栈的实现分析
先考虑需要实现的功能(考虑结构设计时是从需要实现的功能出发的):
- 初始化
- 入栈
- 出栈
- 获取栈顶元素
- 获取栈中有效元素的个数
- 判空。栈为空返回true;不为空返回false
- 销毁
再考虑栈的结构定义
可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。
这里实现动态数组栈。
这里由于是动态增长的栈,在栈这个结构中应当有一个动态数组,另外还需要一个变量表示数组中有效元素数量,以及数组实际大小(容量)以便确定是否需要扩容。这一点和顺序表很类似。
结构定义
//先定义数据类型
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
初始化栈
在这里我们实现的栈是由使用方定义并传其地址给函数初始化,
而不是由函数创建栈并返回指向这个栈的指针。
top标记的是下一个数据放入位置的下标。
void StackInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->top = 0;
ps->capacity = 0;
}
销毁栈
数组栈是一段连续的空间,由realloc实现,释放一次就够了。
void StackDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->top = ps->capacity = 0;
}
入栈
入栈前需要判断栈是否满了,满了就扩容。这里和顺序表的处理方法是一样的。
void StackPush(ST* ps, STDataType x)
{
assert(ps);
if(ps->top == ps->capacity)
{
int newcapacity = ps->capacity == 0