目录
1结构和概念
栈是一种特殊的线性表,只允许在固定的一段插入数据和删除数据的操作,进行数据插入和的删除一段叫做栈顶,另一端成为栈底。栈中的所有元素都都遵循先入后出(LIFO--Last In First Out)。
压栈:栈的插入叫做进栈/入栈/压栈,入数据在栈顶。
出栈:栈的删除叫做出栈。出数据也在栈顶。
2.栈的实现
前面所说的栈是一种特殊的线性表所以我们可以使用前面的链表和顺序表线性结构来实现,在我们操作的时候因为我们需要找顶,顶的位置就是我们插入和删除的位置,为了减小成本我们用顺序表实现就足够了。
1.结构的定义
一般的栈是不能实现空间扩充的,但是我们为了提高实现难度我们选择灵活空间的顺序表。
不可增加空间的顺序表:
#define M 8;
typedef int DataStackType;
struct ListStack
{
DataStackType _arr[M];
int size;
};
可增加空间的顺序表:
typedef int DataStackType;
typedef struct ListStack
{
DataStackType* arr;
int capacity;
int size;
}LS;
这里我们统一使用可以增长的栈。
2.栈函数的实现
我们需要使用栈我们需要它具有出栈,入栈,初始化,销毁的功能。
2.2.1初始化
这个代码十分简单不多做讲解直接上代码:
void StackInit(Stack* ps)
{
assert(ps);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
2.2.2 入栈的函数
我们这个函数需要入栈,我们需要传递两个参数,一个是栈底地址还有入栈的参数。同时我们写的是一个可以增长的栈所以我们在插入时还需不需要扩容,我们把数据插入后还需要对size++;
void StackPush(Stack* ps, STDataType data)
{
assert(ps);
//扩容
if (ps->capacity == ps->top)
{
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
STDataType* newa = (STDataType*) realloc(ps->a,newcapacity * sizeof(STDataType));
if (newa == NULL)
{
perror("realloc fail");
return;
}
ps->capacity = newcapacity;
ps->a = newa;
}
ps->a[ps->top] = data;
ps->top++;
}
2.2.3出栈
我们需要对栈顶元素出栈,我们就直接size--就行了,我们也不会访问到被出栈的元素。
void StackPop(Stack* ps)
{
assert(ps);
if (!StackEmpty(ps))
{
return;
}
else
{
ps->top--;
}
}
2.2.4输出栈顶数据
我们定义的size是指向的栈顶的下一个元素我们想输出代码如下所示:
STDataType StackTop(Stack* ps)
{
assert(ps);
if (!StackEmpty(ps))
{
return;
}
else
{
return ps->a[ps->top - 1];
}
}
2.2.5获得栈中的元素个数
我们的size就是栈的元素个数,代码十分简单直接上代码。
int StackSize(Stack* ps)
{
assert(ps);
return ps->top;
}
2.2.6判断我们的栈是否为空
我们使用Bool变量我们直接return size就行了非0为真为0为假,代码如下:
_Bool StackEmpty(Stack* ps)
{
return ps->top;
}
2.2.7销毁栈
想要销毁栈我们就需要把栈底的首地址释放掉我们再把该指针置空。
void StackDestroy(Stack* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
3.栈元素的输出
我们完成函数后会出现一个问题就是栈的元素的输出有两个方式:我们可以只用函数,还有一种用循坏来把它当做函数来遍历。
我们就讲第二种为什么不用第一种后面还会讲解C++在类和对象是会讲到:
我们需要一个循环,循环跳出的条件是栈为空,我们没top一次就需要pop一次这样得到栈里面的所有数据代码如下:
while (StackEmpty(&pa))
{
STDataType a = StackTop(&pa);
printf("%d ", a);
StackPop(&pa);
}
其中pa就是我们的栈。