【数据结构】——4.栈
一、栈的概念及结构
1. 栈的概念
栈(Stack):一种特殊的线性表,只允许固定的一端插入和删除。进入数据插入和删除操作的一端称为栈顶,另一端称为栈底
栈元素遵守后进先出LIFO(Last in First Out)原则
栈顶插入也叫入栈、进栈,删除也叫做出栈、弹栈
栈可分为顺序栈和链栈
系统栈:是操作系统的概念,用内存进行区域划分,创建函数栈帧时就会使用,与我们实现的栈不同,我们的栈在堆空间内申请,用于数据的存储操作。
2. 顺序栈结构定义
typedef int STDataType;
typedef struct Stack
{
STDataType* data; //栈空间数组
int top; //栈顶位置
int capacity; //栈容量
} Stack;
二、栈的实现
1. 初始化
- 这里传入二级指针,先为Stack分配空间,扩容时再为data域分配空间
- 初始化时将各成员变量赋初值
void StackInit(Stack** pps)
{
assert(pps != NULL);
*pps = (Stack*)malloc(sizeof(Stack));
if (*pps == NULL)
{
perror("malloc fail\n");
exit(-1);
}
(*pps)->data = NULL;
(*pps)->capacity = 0;
(*pps)->top = 0;
}
2. 入栈
- 先检查是否栈满,若是满了,则进行扩容(这里以2倍的方式扩容)
- 再将数据插入栈顶,栈顶指针上移
void StackPush(Stack* ps, STDataType x)
{
assert(ps != NULL);
if (ps->top == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
STDataType* temp = (STDataType*)realloc(ps->data, newcapacity * sizeof(STDataType));
if (temp == NULL)
{
perror("realloc fail\n");
exit(-1);
}
ps->capacity = newcapacity;
ps->data = temp;
}
ps->data[ps->top] = x;
ps->top++;
}
3. 出栈
- 出栈仅仅只是对栈顶指针下移即可
- 出栈前先检查是否为空,这里对为空的情况不做处理
void StackPop(Stack* ps)
{
assert(ps != NULL);
if (ps->top == 0)
{
return;
}
ps->top--;
}
4. 获取栈顶元素
获取之前先判断栈是否为空
STDataType StackTop(Stack* ps)
{
assert(ps != NULL);
assert(ps->top != 0);
return ps->data[ps->top - 1];
}
5. 获取栈元素个数
栈顶减栈底就是栈元素个数
size_t StackSize(Stack* ps)
{
return (size_t)(ps->top);
}
6. 判断栈是否为空
_Bool StackEmpty(Stack* ps)
{
assert(ps != NULL);
return ps->top == 0;
}
7. 栈的销毁
先销毁data空间,再销毁stack空间
void StackDestroy(Stack** pps)
{
assert(pps != NULL);
free((*pps)->data);
free(*pps);
*pps = NULL;
}
三、完整代码
代码保存在gitee中:点击完整代码参考