目录
前言
什么是栈?
栈的定义及初始化
栈的定义
栈的初始化
栈的判空
栈顶压栈
栈顶出栈
栈的数据个数
栈的销毁
完整代码
总结
- 学了相当长一段时间的链表,总算是跨过了一个阶段。从今天开始我们将进入栈和队列的学习,相比于链表可以说是有手就行的难度,所以各位老铁可以轻松一波啦,不必太担心。
- 栈和队列我们分开来讲,本篇主要详解栈及其实现
- 栈的特点是先进后出,后进先出(LIFO),这一特点以及进一步运用(单调栈)是一些算法题的突破口,后续我也会分享LeetCode的一些题,希望大家关注点点,以免错过哦!
我们前面学习的顺序表(数组)以及链表可以说是数据结构的物理结构,而栈和队列则是数据结构的逻辑结构。
这是什么意思呢?
如果把数据结构比作活生生的人,那么物理结构就是人的血肉和骨骼,看得见摸得着,在内存中也实际存储这;逻辑结构则是思想灵魂,看不见摸不着,它依赖于物理结构而存在。
简而言之,栈和队列其实都是由数组或者链表实现的,不过在此基础上加了一些限制条件以适用于不同场景,将其抽化成了一个数据结构
typedef int STDataType;
typedef struct Stack
{
int top;
int capacity;
STDataType* a;
}ST;
以下为函数接口实现:
void StackInit(ST* ps)
{
assert(ps);
ps->capacity = ps->top = 0;//指向最后一个数据的下一个
ps->a = NULL;
}
上文提到top间接表示了存储数据的个数,所以我们直接判断top是否为0即可。
以下为函数接口实现:
bool StackEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
以下为函数接口实现:
void StackPush(ST* ps, STDataType x)
{
assert(ps);
//当内存满了则需要扩容
if (ps->top== ps->capacity)
{
int newcapacity = (ps->capacity == 0) ? 4 : ps->capacity * 2;
STDataType *tmp=(STDataType*)realloc(ps->a, newcapacity);
if (tmp == NULL)
{
perror("malloc fail\n");
return;
}
else
{
ps->capacity = newcapacity;
ps->a = tmp;
}
}
//没满就直接压栈即可
ps->a[ps->top] = x;
ps->top++;
}
以下为函数接口实现:
void StackPop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
ps->top--;
}
以下为函数接口实现:
int StackSize(ST* ps)
{
assert(ps);
return ps->top;
}
获取栈顶元素
以下为函数接口实现:
STDataType StackTop(ST* ps)//获得栈顶元素
{
assert(ps);
assert(!StackEmpty(ps));
return ps->a[ps->top-1];
}
切记不可直接free掉代表栈的结构体就以为把栈销毁了,要先free掉结构体里的数组,然后再free掉代表栈的结构体,不然会内存泄漏!!!
以下为函数接口实现:
void StackDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->a=NULL;
ps->top=ps->capacity=0
}
void StackInit(ST* ps)
{
assert(ps);
ps->capacity = ps->top = 0;//指向最后一个数据的下一个
ps->a = NULL;
}
bool StackEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
void StackPush(ST* ps, STDataType x)
{
assert(ps);
//当内存满了则需要扩容
if (ps->top== ps->capacity)
{
int newcapacity = (ps->capacity == 0) ? 4 : ps->capacity * 2;
STDataType *tmp=(STDataType*)realloc(ps->a, newcapacity);
if (tmp == NULL)
{
perror("malloc fail\n");
return;
}
else
{
ps->capacity = newcapacity;
ps->a = tmp;
}
}
//没满就直接压栈即可
ps->a[ps->top] = x;
ps->top++;
}
void StackPop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
ps->top--;
}
STDataType StackTop(ST* ps)//获得栈顶元素
{
assert(ps);
assert(!StackEmpty(ps));
return ps->a[ps->top-1];
}
int StackSize(ST* ps)
{
assert(ps);
return ps->top;
}
void StackDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->a=NULL;
ps->top=ps->capacity=0
}
相比于链表,栈实现起来简直不要简单太多,但是大家别懈怠,后面还有二叉树在等着我们呢,现在只是过渡期,继续努力哦!
❤️我也会继续输出数据结构相关的博客的,希望大家多多支持!!!
感谢阅读本小白的博客,如果错误请指出,一定虚心采纳!