栈(stack)是限定仅在表尾进行插入和删除操作的线性表。
一、基本概念
栈是一种后进先出的数据结构。
允许插入和删除的一段称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈。栈又称为后进先出的线性表。
1.1 实现方式
根据栈的实现方式,可以分为两类:
1.1.1 顺序栈
用数组的方式存储。
#define MAX_SIZE 100
// 栈的管理结构
typedef struct{
int data[MAX_SIZE]; //存储栈元素的数组
int top; //栈顶序号
}Stack;
/*
初始化栈
*/
void init(Stack * st)
{
st->top = -1; //假设指向下标-1时,表示空栈,top永远直接指向栈顶元素。
}
/*
压栈
返回值 -1:压栈失败 ;0 :压栈成功。
*/
int push(Stack * st, int val)
{
if(st->top == MAX_SIZE - 1) //栈已满
return -1;
st->data[++st->top] = val;
return 0;
}
/*
出栈
返回值 -1:出栈失败 ;0 :出栈成功。
*/
int pop(Stack * st, int * val)
{
if(st->top == -1)
return -1;
*val = st->data[st->top--];
return 0;
}
以数组方式实现栈往往需要事先确定数组容量的大小。
扩展:
假设有两个存储类型相同的栈,如果为这两个栈各自开辟数组空间,极有可能第一个栈满了,再进栈就溢出了,而另一个栈还有很多存储空间。
针对这类情况,我们可以通过一个数组来存储两个栈。
思路:两个栈的栈底分别置于数组的两段,然后两个栈均向数组中间生长。
#define MAX_SIZE 100
// 栈的管理结构
typedef struct{
int data[MAX_SIZE];
int top1;
int top2;
}Stack;
/*
初始化栈
*/
void init(Stack * st)
{
st->top1 = -1;
st->top2 = MAX_SIZE;
}
/*
压栈
返回值 -1:压栈失败 ;0 :压栈成功。
*/
int push(Stack * st, int val, int lrst)
{
if(st->top1 + 1 == st->top2) //栈满了
return -1;
if(lrst == 1) //栈1有元素进栈
st->data[++st->top1] = val;
else if(lrst == 2) //栈2有元素进栈
st->data[--st->top2] = val;
return 0;
}
/*
出栈
返回值 -1:出栈失败 ;0 :出栈成功。
*/
int pop(Stack * st, int * val,int lrst)
{
if(lrst == 1)
{
if(st->top1 == -1)
return -1;
*val = st->data[st->top1--];
}
else if(lrst == 2)
{
if(st->top2 == MAX_SIZE)
return -1;
*val = st->data[st->top2++];
}
return 0;
}
1.2.2 链式栈
用链表的方式实现。
/*
栈元素节点
*/
typedef struct StackNode{
int data;
StackNode * pre; //指向前一个元素, 指向栈底方向。 个人认为用pre比用next形象。
}StackNode;
typedef struct Stack{
StackNode * top;
int cnt; //栈的元素个数
}Stack;
// 初始化栈
void init(Stack * st)
{
st->top = NULL;
st->cnt = 0;
}
/*
压栈
返回值 -1:压栈失败 ;0 :压栈成功。
*/
int push(Stack * st, int val)
{
StackNode * node = new StackNode;
if (!node) //申请内存失败
return -1;
node->data = val;
node->pre = st->top; //新入栈的元素的前一个元素是之前的栈顶元素。
st->top = node; //修改栈顶为新入栈的元素
st->cnt++; //栈元素数量+1
return 0;
}
/*
入栈
返回值 -1:出栈失败 ;0 :出栈成功。
*/
int pop(Stack * st, int * val)
{
if (st->cnt == 0) //空栈
return -1;
*val = (st->top)->data;
StackNode * node = st->top;
st->top = node->pre;
delete node;
st->cnt--;
return 0;
}
二、std::stack
C++ STL 中提供了栈的实现 —— std::stack
。是一个容器适配器,下层容器默认是std::deque
。 可参考 C/C++ 语言参考
std::stack
所有元素的