
个人主页:小则又沐风a
个人专栏:数据结构
目录
[一 栈的概念和结构](#一 栈的概念和结构)
[二 栈的实现](#二 栈的实现)
[1. 结构定义](#1. 结构定义)
[2. 初始化栈](#2. 初始化栈)
[3. 入栈](#3. 入栈)
[4. 出栈](#4. 出栈)
[6. 获取栈的有效的元素的个数](#6. 获取栈的有效的元素的个数)
[8. 销毁栈](#8. 销毁栈)
在之前我们讲解了有关链表知识点,下面我们来看另一种数据结构: 栈.
一 栈的概念和结构
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶。

这样看起来栈的结构是不是很像羽毛球桶.

二 栈的实现
栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的 代价比较小.


示意图如上.
现在我们来实现栈的结构.
1. 结构定义
cpp
#define _CRT_SECURE_NO_WARNINGS 1
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int _top; //栈顶
int _capacity;//容量
}Stack;
我们可以看出来这个栈的结构和顺序表的结构非常相似,

2. 初始化栈
cpp
void StackInit(Stack* ps)
{
ps->a = NULL;
ps->_capacity = ps->_top = 0;
}
3. 入栈
cpp
void StackPush(Stack* ps, STDataType data)
{
assert(ps);
if (ps->_top == ps->_capacity)
{
int newcapacity = ps->_capacity;
if (newcapacity == 0)
{
newcapacity = 4;
}
else
{
newcapacity = ps->_capacity * 2;
}
STDataType* temp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newcapacity);
if (temp == NULL)
{
perror("realloc");
return;
}
ps->a = temp;
ps->_capacity = newcapacity;
}
ps->a[ps->_top] = data;
ps->_top++;
}
在我们入栈的时候,我们先要判断栈的内存是否足够让我们继续添加数据,
也就是这一步,为什么可以这样写呢?
是因为我们在初始化的时候我们将top的数据初始化为了0,
那么top就代表的是栈顶的下一个数据的位置.
然后下面的步骤和顺序表的类似.
4. 出栈
cpp
void StackPop(Stack* ps)
{
assert(ps);
assert(ps->_top > 0);
ps->_top--;
}
出栈很简单我们只需要将数据个数减减即可.

注意在数据个数为0的时候我们不能继续出栈了.
5.获得栈顶的数据
cpp
STDataType StackTop(Stack* ps)
{
assert(ps);
assert(ps->_top > 0);
return ps->a[ps->_top - 1];
}
6. 获取栈的有效的元素的个数
cpp
int StackSize(Stack* ps)
{
assert(ps);
return ps->_top;
}
7.检测栈是否为空,如果为空返回非零结果,如果不为空返回0
cpp
int StackEmpty(Stack* ps)
{
assert(ps);
if (ps->_top == 0)
{
return 0;
}
else
{
return 1;
}
}
8. 销毁栈
cpp
void StackDestroy(Stack* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->_capacity = ps->_top = 0;
}
以上就是我们栈的接口的实现.这个栈看起来难实际上在我们理解过后他就会变的简单了.
之后 我将会讲解数据结构中队列的实现.
谢谢大家的观看!!!