数据结构之栈
一、栈的概念与结构。
1、概念:栈是限定仅在表尾进行插入和删除操作的线性表。栈中的数据元素遵守后进先出原则,即LIFO(Last In First Out)的原则。
2、栈的插入操作:进栈/压栈/入栈
栈的删除操作: 出栈/弹栈
3、进栈出栈的变化形式(重要)
我们想一下,是否最先进栈的元素,就只能最后出栈呢?
其实不然。举例如下:
例如:我们现在要将1、2、3依次进栈,那么会出现哪些出栈顺序呢?
(1)1、2、3一次进栈,再出栈,则顺序为:3->2->1
(2)1、2先进栈,然后出栈2,再进栈3,再一次出栈,则顺序为:2->3->1
(3)1、2先进栈,然后一次出栈2、1,再进栈3,再出栈3,则顺序为:2->1->3
(4)1进栈,1出栈,2进栈,2出栈,3进栈,3出栈,则顺序为:1->2->3
(5)1进栈,1出栈,2、3进栈,再依次出栈,则顺序为:1->3->2
注意:虽然出栈情况多,但是一定不会出现3->1->2的出栈方式。因为要3出栈,则必须让1、2先进栈,当3出栈时,后续出栈的顺序为2->1,不可能为1->2
二、栈的实现
栈的头文件(Stack.h)
// 支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{
STDataType* _a;
int _top; // 栈顶
int _capacity; // 容量
}Stack;
// 初始化栈
void StackInit(Stack* ps);
// 入栈
void StackPush(Stack* ps, STDataType data);
// 出栈
void StackPop(Stack* ps);
// 获取栈顶元素
STDataType StackTop(Stack* ps);
// 获取栈中有效元素个数
int StackSize(Stack* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
int StackEmpty(Stack* ps);
// 销毁栈
void StackDestroy(Stack* ps);
(1)检查栈空间的容量
void CheckCapacity(Stack* ps)
{
if (ps->size >= ps->capacity)
{
ps->capacity *= 2;
ps->array = (STDataType *)realloc(ps->array, ps->capacity * sizeof(STDataType));
}
}
(2)栈的初始化
void StackInit(Stack* ps)
{
ps->array = (STDataType *)calloc(DEFSTACKSIZE, sizeof(STDataType));
ps->capacity = DEFSTACKSIZE;
ps->size = 0;
}
(3)头插
void StackPush(Stack* ps, STDataType x)
{
CheckCapacity(ps);
ps->array[ps->size++] = x;
}
(4)尾删
void StackPop(Stack* ps)
{
if (ps->size == 0)
{
return;
}
ps->size--;
}
(5)返回栈空间的栈顶元素
STDataType StackTop(Stack* ps)
{
assert(ps);
assert(ps->size);
return ps->array[ps->size - 1];
}
(6)判断栈空间元素是否为空
int StackEmpty(Stack* ps)
{
return ps->size == 0;
}
(7)返回栈空间的元素个数
int StackSize(Stack* ps)
{
assert(ps);
return ps->size;
}
(8)销毁栈空间
c
void StackDestory(Stack* ps)
{
if (ps->array)
{
free(ps->array);
ps->array = NULL;
ps->size = 0;
ps->capacity = 0;
}
}