1.栈
1.1 栈的概念及结构
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。
进行数据插入和删除操作的一端
称为
栈顶
,另一端称为
栈底
。
栈中的数据元素遵守后进先出
LIFO
(
Last In First Out
)的原则。
1.1.1 压栈和出栈
压栈:栈的插入操作叫做进栈
/
压栈
/
入栈,
入数据在栈顶
。
出栈:栈的删除操作叫做出栈。
出数据也在栈顶
1.2 栈的实现
栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。
1.1.2 Top (栈顶)的初始设计问题
当我们设计一个基础栈时遇到如何表示一个空栈时,可能会不假思索的认为栈中Top为0时不正是代表空栈吗?
此时我们需要注意一个问题:空栈时Top的状态设置为0;插入一个元素时Top依然为0。
这样不利于我们通过Top立刻判断栈是否为空,所以我们有两种设计方法:
方案一:Top设计为-1
方案二(推荐):Top设置为0;但表示指向栈顶下一个元素位置。
好处:Top表示栈中元素个数。
1.2.3 栈设计
// 支持动态增长的栈typedef int STDataType ;typedef struct Stack{STDataType * _a ;int _top ; // 栈顶int _capacity ; // 容量} Stack ;
1.3 栈功能实现
//栈接口(Top设计为指向栈顶下一元素)
//栈的初始化
void StcakInit(Stack* pStack)
{
//规避传来空指针
assert(pStack);
pStack->a = NULL;
pStack->Top = 0;
pStack->capacity = 0;
}
//插入元素
void StackPush(Stack* pst,STDataType x)
{
assert(pst);
//判断栈是否满了,如果满了则扩容。
if (pst->Top == pst->capacity)
{
//使用三目运算符:如果capacity为0 则直接按10扩容, 否则按自身2倍扩容。
STDataType newcapacity = pst->capacity == 0 ? 10 : pst->capacity * 2;
STDataType* newstack =(STDataType*) realloc(pst->a,newcapacity*sizeof(STDataType));
pst->capacity = newcapacity;
pst->a = newstack;
}
//插入 x 数据
pst->a[pst->Top] = x;
pst->Top++;
}
//删除栈顶元素
void StackPop(Stack* pst)
{
assert(pst);
assert(pst->Top > 0);
pst->Top--;
}
//取栈顶元素
STDataType StackTop(Stack* pst)
{
assert(pst);
//保证栈内至少有 1 个元素。
assert(pst->capacity > 0);
return pst->a[pst->capacity-1];
}
//计算栈空间大小
STDataType Stacksizeof(Stack* pst)
{
assert(pst);
return pst->capacity;
}
//判断栈是否为空栈
bool StackEmpty(Stack* pst)
{
assert(pst);
return pst->Top == 0;
}
//栈的销毁
void StackDestroy(Stack* pst)
{
assert(pst);
//free会自动判断指针是否为空指针
free(pst->a);
pst->a = NULL;
pst->capacity = 0;
pst->Top = 0;
}