[絮絮叨叨叨叨叨…
栈是后进先出的结构,说白了就是尾删尾插,能快速实现尾删尾插的结构是什么呢,当然是我们的顺序表结构,它的存储空间是连续的,要找什么数,一下子就找到了,不需要像链表一样从头找到尾.
先创一个结构体,用来代表栈
typedef int STDataType;
typedef struct Stack
{
STDataType* a;//指向顺序表的指针
int top;//栈顶
int capacity;//栈容量
}Stack;
初始化栈
申请一个栈变量后一定要初始化哦不然就会报错报错报错
//初始化栈
void StackInit(Stack* ps)
{
ps->a = NULL;
ps->top = 0;
ps->capacity = 0;
}
判断栈满函数
栈满则扩容.请记住栈满的条件:ps->top==ps->capacity.即栈中有效数据的个数正好等于栈的容量.
void StackFull(Stack* ps)
{
if (ps->top == ps->capacity)
{
//扩容:若原容量为0,则新容量为4,否则,新容量为原容量的两倍
int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
STDataType* temp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newcapacity);
if (temp == NULL)//扩容失败
{
perror("realloc fail:");
exit(-1);
}
ps->a = temp;
ps->capacity = newcapacity;
}
}
判断栈空
栈空就不能再出栈了哦~该函数栈空就返回非0值
//判断栈空
int StackEmpty(Stack* ps)//栈为空返回非0的值
{
assert(ps);
if (ps->top == 0)
{
return -1;
}
return 0;
}
栈的销毁
栈用完之后要及时销毁,不然会造成内存泄漏[尊嘟]
//销毁栈
void StackDestroy(Stack* ps)
{
free(ps->a);
ps->a = NULL;
ps->top = 0;
ps->capacity = 0;
}
入栈
入栈要判断栈是否已经满了,满了之后要扩容,上面的扩容函数可不是白写的[哼`
//入栈
void StackPush(Stack* ps, STDataType data)
{
assert(ps);
//判断栈满->栈满则扩容
StackFull(ps);
ps->a[ps->top] = data;
ps->top++;
}
出栈
出栈的条件是ps->top>0;[说明至少还有一个数据],这里就简单粗暴的用assert解决了[啦啦啦`
/出栈
void StackPop(Stack* ps)
{
assert(ps);
assert(ps->top > 0);
--ps->top;
}
获取栈顶元素
//获取栈顶元素
STDataType StackTop(Stack* ps)
{
assert(ps);
assert(ps->top > 0);
STDataType ret = ps->a[ps->top - 1];
return ret;
}
最后是我的源码:需要源码的小伙伴请移驾到我的Gitee
最后再说一句[废话真多~滚
想知道自己有没有学会写栈啦,就取试试Leetcode的有效括号