一:栈的概念
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
二:双向链表的实现
第一点:
本文采用三个文件进行实现
1:Stack.h(对实现函数以及栈的声明)
2:Stack.c(相关函数的实现)
3:text.c(对程序的使用检测)
第二点:
所有的函数都要对接受到的结构体指针进行assert,确保程序的严谨性。而且部分还会会assert是否存在元素,比如pop函数(删除函数)。
三:函数的实现讲解
前提:栈的声明
解释:
1:a是一个指针,用来指向一个数组。
2:top这个变量通常用来追踪栈顶元素的位置,top为0代表数组是空的,并且 top
指向的是数组中下一个可插入元素的位置。随着数据的插入删除,top也会+-,并且之后的删除插入都要靠top去作为数组下标的基础,在top的基础上进行下标的修改。
3:capacity代表栈的容量。
4:将类型进行一个typedef,方便之后的类型改变带来的修改,只需要修改int即可。
5:将结构体重命名为LTNode,方便之后使用。
第一个函数:初始化栈
解释:
1:对指针的初始化一般是置空。
2:其他变量top和capacity的赋值0。
第二个函数:入栈函数(重点)
解释:
1:入栈第一步应该判断容量是否允许插入,top和capacity相等,只有两种情况:
第一种:第一次入栈。
第二种:容量满了
此处用了三目操作符,pc->capacity是否为0,是的话,就让容量变成4,否则让容量翻倍.
2: 不管是哪种情况,都应该去开辟空间给a了,所以我们采用realloc。此处两个重点:
第一个问题:为什么第一次开辟不用malloc?
因为:我们初始化a = NULL了,在realloc函数中,接收的指针为NULL,realloc就等同于malloc了。
第二个问题:为什么不直接用a来接收开辟的空间,而是用了一个tmp中间变量,最后在赋值给a?
因为:如果用a接收,那realloc开辟失败,a如果之前不是空栈,那之前的栈元素也会丢失,而用一个tmp去接受,再去判断是否开辟成功会更好的保护数据。
3:将x赋给a[top],因为top指向栈顶,它的值等同于元素的个数,top为下标就代表栈顶的后一个空间。
第三个函数:出栈函数
解释:
让top--即可,因为top指向栈顶,这样如果下一个要入栈,根据入栈函数,它应该去占用之间4占用的空间。
第四个函数:返回栈顶元素
解释:
1:assert 是否存在元素,没有元素,何来栈顶?
2:因为top指向栈顶元素,但由于下标规则,所以下标为top-1即可返回栈顶元素。
第五个函数:获取栈中元素个数
解释:
1:因为top的值和元素的个数一致,top一开始为0,入栈一个就top+1.出栈一个就top-1,所以直接返回top即可。
第六个函数:检测栈是否为空
解释:
1:bool值要么为true要么为false,top为0则true,反之false。
第七个函数:销毁栈
解释:
1:释放a,置空a,其余变量赋值0即可。
最后是text.c函数进行一系列测试的运行结果:
头文件的展示: