这里写目录标题
- 栈的定义与性质
- 栈的实现
- 栈的定义
- 栈的功能
- 栈的创建
- 入栈
- 出栈
- 栈顶
- 判断栈为空
- 得到栈的个数
- 栈的销毁
栈的定义与性质
第一个问题:什么是栈?
栈的定义是:
一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。
进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。
栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
分解一下就是:
首先是顺序表
只在一个端口进行数据插入和删除,这个端口叫做栈顶
另一个端口叫做栈底
元素的顺序遵循后进先出,先进后出的原则
第二个问题就是
什么是先进后出,什么是后进先出
就和手枪一样,在弹夹中,先压进去的子弹在弹夹的底部,后压入的子弹在弹夹的顶部,在顶部的子弹会先射出来
图解就是这样
这里是按照顺序入栈的方式,但是我们也可以不用顺序入栈,而是乱序入栈,结果就可能不一样
这个是栈的基本性质,针对这个基本性质,我们就能够实现栈
栈的实现
栈的定义
第一个问题,我们用顺序表还是链表实现?
栈的实现可以使用数组或者链表,但是相对而言数组的尾插是直接用最后一个下标插入就能够实现的,实现代价很小
所以我们使用数组
然后就是如何定义栈的问题
栈有如下特性,一块空间,栈顶部的位置,由于我们要动态使用栈,所以还要有栈空间的大小
struct Stack
{
StackData* a;
int top;
int cap;
};
栈的功能
栈有哪些功能?
栈的创建,栈的销毁,入栈,出栈,判断栈为空,统计栈元素个数,获得栈顶元素
栈的创建
栈的创建本质是数组的创建
定义数组默认大小为 4
对空间进行开辟
为何要传地址,因为我们修改的是函数外部的栈,要用地址修改
void StackInit(Stack* qs)
{
//暂时取4个字节大小
Stackdata* arr = (Stackdata*)malloc(sizeof(Stackdata)*4);
if (arr == NULL)
{
perror("malloc fail");
exit(-1);
}
qs->a = arr;
qs->top = 0;
qs->cap = 4;
}
入栈
入栈,数据存放在最后的位置上
根据设定,我们的top用来描述占中存放的数据个数
也就是下一个数据要插入的位置
所以入栈
就是,如果空间足够就入栈,不足就开辟空间
然后 top++
程序
void StackPush(Stack* qs, Stackdata x)
{
if (qs->top == qs->cap)
{
int newcap = qs->cap * 2;
Stackdata* newarr = (Stackdata*)realloc(qs->a,newcap*sizeof(Stackdata));
if (newarr==NULL)
{
perror("realloc failed");
exit(-1);
}
qs->a = newarr;
qs->cap = newcap;
}
qs->a[qs->top] = x;
qs->top++;
}
需要注意的是 因为 top 是 qs 结构体的一个内容
所以索引是 qs->top
存放数据应该放的位置是 qs->a[qs->top]
出栈
出栈的过程就是访问不到 top 上一个位置的元素
访问不到的意思就是
下一次插入,这个数字不会阻挡插入
访问栈头,不会访问到这个数
所以只要 top – 就能够达到这个效果
同时如果为空就不能出栈
void StackPop(Stack* qs)
{
if (StackEmpty(qs))
{
printf("出栈失败,已经空了\n");
return;
}
qs->top--;
}
栈顶
栈的使用是获取栈顶的元素
当栈不为空的时候
Stackdata StackTop(Stack* qs)
{
assert(!StackEmpty(qs));
return qs->a[qs->top-1];
}
assert 说明就是当栈为空的时候 直接报错
因为在设置中 top 是栈元素个数,所以栈顶为 top-1 位置上的元素
判断栈为空
当 top == 0 的时候
栈为空
程序
bool StackEmpty(Stack* qs)
{
if (qs->top == 0)
{
return true;
}
return false;
}
得到栈的个数
因为 top 本身统计的就是数字个数
所以程序
int countStack(Stack* qs)
{
return qs->top;
}
栈的销毁
销毁后
结构体中数组空间释放,并且把参数置为 0
void StackDestroy(Stack* qs)
{
assert(qs);
free(qs->a);
qs->a = NULL;
qs->cap = 0;
qs->top = 0;
}
希望大家看完,能够有所收获
如果有错误,请指出我一定虚心改正
动动小手点赞
鼓励我输出更加优质的内容