1、什么是栈?栈有什么特性?
栈是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的元素遵守后进先出LIFO(last in first out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶。
2、栈的实现
栈的实现一般可以用数组或者链表实现,相对而言数组的结构实现更优,因为数组在尾部插入或删除数据操作还是比较方便的。
下面我们在代码的实现中看一下具体应该如何来做。
支持动态增长的栈
typedef int SDataType;
typedef struct Stack
{
SDataType* _array;//指向一段空间用来存放栈的元素
int _top;//栈顶或者有效元素的个数
int _capacity;//容量
}Stack;
要实现的操作:
void StackInit(Stack* ps);//栈的初始化
void StackDestory(Stack* ps);//销毁栈
void StackPush(Stack* ps, SDataType data);//入栈
void StackPop(Stack* ps);//出栈
SDataType StackTop(Stack* ps);//查看栈顶元素
int StackEmpty(Stack* ps);//栈是否为空
int StackSize(Stack* ps);//栈中的有效元素个数
栈的初始化:
初始状态下容量设置为3,有效元素此时为0。
void StackInit(Stack* ps) {
assert(ps);
ps->_array = (SDataType*)malloc(sizeof(SDataType)*3);
if (ps->_array == NULL) {
assert(0);
return;
}
ps->_capacity = 3;
ps->_top = 0;
}
销毁栈:释放掉之前申请的内存空间,并将容量与有效元素个数都置零。
void StackDestory(Stack* ps) {
assert(ps);
if (ps->_array) {
free(ps->_array);
ps->_capacity = 0;
ps->_top = 0;
}
}
入栈:
入栈之前需要先检测栈内空间是否已满。使用CheckCapacity来实现。
如果已满:扩容
未满:直接压入数据
void StackPush(Stack* ps, SDataType data) {
CheckCapacity(ps);
ps->_array[ps->_top++] = data;
}
检测容量:若不够则扩容,从而实现一个动态栈
void CheckCapacity(Stack* ps) {
assert(ps);
if (ps->_capacity == ps->_top) {
int newCapacity = ps->_capacity * 2;
SDataType* pTemp = (SDataType*)malloc(sizeof(SDataType)*newCapacity);
if (pTemp == NULL) {
assert(0);
return;
}
for (int i = 0; i < ps->_top; ++i) {
pTemp[i] = ps->_array[i];
}
free(ps->_array);
ps->_array = pTemp;
ps->_capacity = newCapacity;
}
}
出栈:若栈空,则返回。非空则top自减。
void StackPop(Stack* ps) {
assert(ps);
if (StackEmpty(ps))
return;
ps->_top--;
}
查看栈顶元素:即top-1处的数据
SDataType StackTop(Stack* ps) {
assert(ps);
return ps->_array[ps->_top - 1];
}
栈是否为空:
int StackEmpty(Stack* ps) {
assert(ps);
return ps->_top == 0;
}
栈中有效元素个数:
int StackSize(Stack* ps) {
assert(ps);
return ps->_top;
}
以上。。。大家可以自己调试看看