栈的定义和特点
栈是一种限定仅在表尾进行插入或删除的线性表,因此,对栈来说,表尾端具有特殊意义,称之为栈顶,相应的,表头称为栈底,不含元素的空表称为空栈。
栈中的元素遵循后进先出的顺序(Last In First Out),简称LIFO顺序。
这里我们实现栈的基本操作实用的是链表,更方标栈插入和删除数据。
栈的实现
类型命名
首先我们先进行类型命名,方便改变栈的数据类型。
typedef int elem;
栈的结构
typedef struct stack
{
elem* a;
int top;//栈顶
int cap;//容量
}ss;
在栈的结构这里,我们使用了三个变量,a为插入的数据,top为栈顶,cap为容量。
初始化
void ini(ss* pst)//初始化
{
assert(pst);
pst->a = NULL;
pst->cap = 0;
pst->top = 0;
}
在这里,我们首先断言一下pst是否为空,若pst为空,则表示栈的创建存在问题,时候将a指针置为空,将栈的栈顶和容量置为0。
入栈
栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
void push(ss* ps,elem x)//入栈
{
assert(ps);
if (ps->cap == ps->top)
{
int newcap = ps->cap == 0 ? 4 : ps->cap * 2;
elem* tmp = (elem*)realloc(ps->a, newcap * sizeof(elem));
if (tmp == NULL)
{
perror("tmp");
return;
}
ps->a = tmp;
ps->cap = newcap;
}
ps->a[ps->top] = x;
ps->top++;
}
我们首先断言ps是否为空,不为空再进行下一步操作,然后用if语句判断栈的栈顶和容量是否相等,如果相等表示栈的容量不足,需要增容,如果是第一次增容,栈顶和容量都为0,此时需要使用三元操作符,如果ps->cap==0时将赋予他为4,然后定义一个tmp来创建空间,随后将tmp的值赋给pa->a,再将新的容量大小的数据给予ps->cap,最后将x传给ps->a[ps->top]位置,再令栈顶的位置+1,方便下一次入栈。
出栈
void pop(ss* ps)//出栈
{
assert(ps);
assert(ps->top > 0);
ps->top--;
}
我们首先断言ps是否为空,然后判断ps里面是否有元素,如果ps里面没有元素,那就停止运行,如果不为空,那就将栈顶位置-1,将之前的数据删除。
取栈顶数据
elem top(ss* ps)//取栈顶数据
{
assert(ps);
assert(ps->top >= 0);
return ps->a[ps->top-1];
}
我们首先断言ps以及ps里面的元素是否为空,如果不为空,那就将返回top位置的元素。
判空
bool emp(ss* ps)//判空
{
assert(ps);
return ps->top == 0;
}
在判断栈是否为空时,我们使用bool类型,如果ps->top==0成立,那就返回true,表示这个栈里面没有元素,如果不成立,那就返回false,表示这个栈里面存在元素。