1,栈:一种特殊的线性表,其只允许在一端进行数据的插入和删除,这一端称为栈顶,还有一端就称为栈底。栈中的数据元素遵循后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作,也叫做进栈,入栈,所插入的数据在栈顶。
出栈:栈的删除操作,所删除的数据在栈顶。
2,栈的结构


这里通过数组的方式实现。
1,首先定义一个栈
typedef struct stack { int* a; //指针指向数组空间,方便进行扩容 int top; //栈顶 int capacity; //栈的大小 }SL;
接下来要实现一些栈的功能 ,有栈的初始化,栈的销毁,入栈,出栈,取栈顶数据,获取栈的元素个数,判断栈是否为空。
2,下面是这些函数的声明:这里都用到一级指针来接收栈的地址。
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
typedef int SLDataType;
typedef struct stack
{
SLDataType* a;
int top; //栈顶
int capacity;//空间大小
}SL;
//初始化栈
void stackInit(SL* s);
//入栈
void stackpush(SL* s, SLDataType data);
//出栈
void stackpop(SL* s);
//取栈顶数据
SLDataType stackop(SL* s);
//判空
bool SLEmpty(SL* s);
//获取数据个数
int size(SL* s);3,接下来是函数的实现
3.1,初始化栈
//初始化栈
void stackInit(SL* s)
{
assert(s);
s->a = NULL;
s->capacity = 0;
s->top = 0; //可以理解为,栈为空时,栈顶top=0,那么top就是指向栈顶的下一个位置。
//s->top=-1 这种情况下,top是指向栈顶的。
}3.2,入栈
//入栈
void stackpush(SL* s, SLDataType data)
{
assert(s);
//如果空间不够,需要扩容
if (s->top == s->capacity)
{
int newcapacity = s->capacity == 0 ? 4 : s->capacity * 2;//用三目操作符计算扩容的大小
//对a进行扩容
SLDataType* st = (SLDataType*)realloc(s->a, newcapacity * sizeof(SLDataType));//这里当a为NULL时,不需要判断,因为realloc第一个参数为空时,realloc和malloc功能一样,直接开辟空间
if (st == NULL)
{
perror("realloc fail");
return;
}
s->a = st; //将新开的空间给a
s->capacity = newcapacity;
}
s->a[s->top] = data; //插入数据
s->top++; //栈顶往后走一位
}3.3出栈
让栈顶top--即可
//出栈
void stackpop(SL* s)
{
assert(s);
assert(s->top > 0);
s->top--;
}3.4取栈顶数据
s->top为栈顶下一个元素,top-1为栈顶元素。
//取栈顶数据
SLDataType stackop(SL* s)
{
assert(s);
assert(s->top > 0);
return s->a[s->top - 1];
}3.5判断栈是否为空
top==0表示栈为空
//判空
bool SLEmpty(SL* s)
{
assert(s);
return s->top == 0;
}3.6获取栈的元素个数
//获取数据个数
int size(SL* s)
{
assert(s);
return s->top;
}3.7栈的销毁
//栈的销毁
void destory(SL* s)
{
assert(s);
free(s->a);//释放空间a
s->a = NULL;//手动置为空
s->top = s->capacity = 0;
}