目录
一、栈的概念
栈可以看作一个装水的容器,允许先进后出(First In Last Out)(FILO)
二、栈的实现
1.Stack.h
我们玩的是顺序栈,还有链式结构实现的栈,大家可以自己去玩。
在栈的设计中,我们需要记录栈顶指针(_top),栈的容量(_capacity),数组(_a)。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#include <assert.h>
typedef int STDataType;
typedef struct Stack {
STDataType* _a;
STDataType _top; //指向栈顶
STDataType _capacity; //记录容量
}ST;
void StackInit(ST *ps); //初始化
void StackPush(ST* ps,STDataType x); //压栈
void StackPop(ST* ps); //出栈
int StackSize(ST* ps);
void StackDestroy(ST* ps); // 销毁栈
void StackPrint(ST* ps); //打印栈的元素
STDataType StackTop(ST* ps); //获取栈顶元素个数
bool StackEmpty(ST* ps); // 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
2.Stack.c
1.初始化栈(StackInit)
_top的目的是为了记录栈顶元素位置,所以有两种写法,一种是将_top大小设置为-1,这样_top的值刚好指向栈顶元素,另一种是_top大小为0。
void StackInit(ST*ps) {
assert(ps);
ps->_a = NULL;
ps->_capacity = 0;
ps->_top = 0;
}
2.压栈(StackPush)
和顺序表的实现类似,在压栈之前我们需要判断栈的容量是否足够,在不够的时候double容量。
如果是链式栈,则是再多实现一个创建节点的函数即可(StackNodeCreate)
void StackPush(ST* ps, STDataType x) {
assert(ps);
if (ps->_top == ps->_capacity) {
int newcapacity = (ps->_capacity == 0 ? 4 : ps->_capacity * 2);
STDataType* temp = (STDataType)realloc(ps->_a, sizeof(STDataType) * newcapacity);
if (temp == NULL) {
perror("realloc fail!");
exit(-1);
}
ps->_a = temp;
ps->_capacity = newcapacity;
}
ps->_a[ps->_top] = x;
ps->_top++;
}
3.出栈(StackPop)
void StackPop(ST* ps) {
assert(ps);
assert(ps->_top > 0);
ps->_top--;
}
4.返回栈大小(StackSize)
int StackSize(ST* ps) {
assert(ps);
return ps->_top;
}
5.销毁栈(StackDestroy)
void StackDestroy(ST* ps) {
assert(ps);
free(ps->_a);
ps->_a = NULL;
ps->_capacity = ps->_top = 0;
}
6.打印栈的元素(StackPrint)
void StackPrint(ST* ps) {
assert(ps);
while (!StackEmpty(ps)) {
print("%d", StackTop(ps));
StackPop(ps);
}
printf("\n");
}
7.获取栈顶元素(StackTop)
STDataType StackTop(ST* ps) {
assert(ps);
assert(ps->_top > 0);
return ps->_a[ps->_top - 1];
}
8.判断栈是否为空(StackEmpty)
bool StackEmpty(ST* ps) {
assert(ps);
return ps->_top == 0;
}
三、总结
总的来说,栈是一个很简单的数据结构,由于其先进后出(头进头出)的特性,我们用顺序结构实现即可,在数组中,数组的尾部是栈顶,数组的头部是栈底。