数据结构之栈详解
![在这里插入图片描述](https://img-blog.csdnimg.cn/8f4490395f5e464597aa0f587707c108.jpg?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5qKm5Lmh5Zue6Zuq,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
一、栈的概念及结构
- 栈:一种特殊的「线性表」,其只允许在 『 固定 』的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为 『 栈顶 』,另一端称为 『 栈底 』。栈中的数据元素遵守『 后进先出LIFO 』(Last In First Out)的原则。
![在这里插入图片描述](https://img-blog.csdnimg.cn/687624d39cec48478c29632405fbfee3.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5qKm5Lmh5Zue6Zuq,size_20,color_FFFFFF,t_70,g_se,x_16)
- 压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在『 栈顶 』。
- 出栈:栈的删除操作叫做出栈。出数据也在『 栈顶 』。
二、栈的实现
1.基本结构
- 栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的 代价比较小。
- 并且栈也可以分为『 静态栈 』(容量有限)和『 动态栈 』(可以扩容)
typedef int STDataType;
#define N 10
typedef struct Stack
{
STDataType _a[N];
int _top;
}Stack;
typedef int STDataType;
typedef struct Stack
{
STDataType* _a;
int _top;
int _capacity;
}Stack;
2.增删查改基本操作
(1)初始化及销毁
- 这里注意初始化栈_capacity 表示最大容量初始为零,_top表示栈顶 可以初始化为0或者-1.
如果是0,那么注意第一个有效元素就是 ps->_capacity[ ps->_top ];
如果是-1,那么注意第一个有效元素就是 ps->_capacity[ ps->_top+1 ];
void StackInit(Stack* ps)
{
ps->_a = NULL;
ps->_capacity = ps->_top = 0;
}
void StackDestroy(Stack* ps)
{
ps->_capacity = ps->_top = 0;
free(ps->_a);
ps->_a = NULL;
}
(2)入栈出栈
- 入栈首先判断ps是否为空,其次判断容量如果是0需要附一个初始值,那么这里假设为4。如果容量不为0 ,则正常2倍扩容,并把新数据赋值。
void StackPush(Stack* ps, STDataType data)
{
assert(ps);
if (ps->_capacity == ps->_top)
{
int newcap = ps->_capacity == 0 ? 4 : ps->_capacity * 2;
ps->_a = (STDataType*)realloc(ps->_a,sizeof(STDataType) * 2 * newcap);
ps->_capacity = newcap;
}
ps->_a[ps->_top++] = data;
}
void StackPop(Stack* ps)
{
assert(ps);
assert(!StackEmpty(ps));
ps->_top--;
}
(3)判空和有效个数
int StackEmpty(Stack* ps)
{
assert(ps);
return ps->_top == 0;
}
int StackSize(Stack* ps)
{
assert(ps);
return ps->_top;
}
(4)返回栈顶元素
STDataType StackTop(Stack* ps)
{
assert(ps);
assert(!StackEmpty(ps));
return ps->_a[ps->_top - 1];
}
总结:栈的操作相较于链表比较简单,同时栈的应用也很多,比如括号匹配问题,表达式求值,模拟递归问题等等,下一篇文章来详细介绍。
测试样例:
void test()
{
Stack s;
StackInit(&s);
StackPush(&s, 1);
StackPush(&s, 2);
StackPush(&s, 3);
StackPush(&s, 4);
printf("%d\n", StackSize(&s));
printf("%d ", StackTop(&s));
StackPop(&s);
printf("%d ", StackTop(&s));
StackPop(&s);
printf("%d ", StackTop(&s));
StackPop(&s);
printf("%d ", StackTop(&s));
StackPop(&s);
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/f5f1964fff1f41a4b17f7e67d2dcdbc7.png)