目录
🍺0.前言
言C之言,聊C之识,以C会友,共向远方。各位博友的各位你们好啊,这里是持续分享
数据结构知识的小赵同学,今天要分享的数据结构知识是栈,在这一章,小赵将会向大家展开聊聊栈。✊
1.栈的概念
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。 栈中的数据元素遵守后进先出 LIFO ( Last In First Out )的原则。两大操作:压栈:栈的插入操作叫做进栈 / 压栈 / 入栈, 入数据在栈顶。出栈:栈的删除操作叫做出栈。 出数据也在栈顶。
栈的演示图:
在我们的数据结构里对栈有这样的一个总结就是先进后出。
那么小赵在这里为了方便大家理解找了一个非常有意思且生动形象的例子,这个例子就是弹夹。
为什么说弹夹就是栈呢?因为你想你往弹夹里面塞子弹的时候是不是都是从上面塞进去,也就可以理解为入栈,但是当你把子弹塞满了,这时候你要卸子弹怎么办,是不是也只能从上面去取,拿这个其实就是出栈。 这个时候各位一想是不是好像和上面的过程很像。所以各位想不起来栈是怎么进出的时候就可以想想弹夹。它也刚好满足我们的先进后出。
当然实在记不住弹夹也没关系,小赵这里还有一个好例子。
就是不知道各位看这个东西的时候没有一种像是一个收衣服的的小盒子,就是这个小盒子把衣服卡的有点死,就是每一件都刚刚好,那么你第一件扔进去的衣服就会压在箱底,而最后放进去的衣服就是在最上面。 也满足我们的先进后出的原理。
2.栈的实现
所以在下面我们实现栈的时候会用数组去实现。当然这时候可能有人要问为啥不用链表去实现一个栈呢?其实这个问题回答起来也简答,各位想想我们上次的链表,每次要找到最后一个的时候都有遍历整个链表,而这个每次都是从最后面插进来,删除去,可不是就比数组要烦吗?
2.1定义一个栈节点
typedef int STDataType;
typedef struct Stack
{
STDataType* _a;
int top; // 栈顶
int capacity; // 容量
}Stack;//这样定义的效果和前面顺序表的效果一样可以增长
2.2入栈
void StackPush(Stack* ps, STDataType data)
{
assert(ps);
if (ps->capacity == ps->top)//栈满了扩栈
{
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newcapacity);
if (tmp == NULL)
{
perror("malloc failed");
return;
}
ps->a = tmp;
ps->capacity = newcapacity;
}
ps->a[ps->top] = data;
ps->top++;//移动栈顶的位置
}
2.3 检测栈是否为空
int StackEmpty(Stack* ps)
{
assert(ps);
return ps->top == 0;//判断如果成立返回非零结果,不成立返回0
}
2.4出栈
void StackPop(Stack* ps)
{
assert(ps);
if (StackEmpty(ps))//如果为空
{
return;
}
ps->top--;//栈顶向下移,只有在栈顶和栈底之间的才是栈存储的元素
}
2.5获取栈中有多少个元素
int StackSize(Stack* ps)
{
assert(ps);
return ps->top;
}
2.6销毁栈
void StackDestroy(Stack* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;//手动制空
ps->top = 0;
ps->capacity = 0;
}
3.试运行
小赵随机弄了一些数据进行试运行,发现没问题。对了这里除了可以直接用结构体,用结构体指针也是可以的。
💎4.结束语
好了小赵今天的分享就到这里了,如果大家有什么不明白的地方可以在小赵的下方留言哦,同时如果小赵的博客中有什么地方不对也希望得到大家的指点,谢谢各位家人们的支持。你们的支持是小赵创作的动力,加油。
如果觉得文章对你有帮助的话,还请点赞,关注,收藏支持小赵,如有不足还请指点,小赵及时改正,感谢大家支持!!!