一、栈的定义
栈又称后进先出线性表,简称LFIO,顾名思义,是只能在表尾进行插入和删除的线性表。
我们假设有一个圆柱形的瓶子,往里面放石头,最先放进瓶子的石头会被压在最底下,必须要等上面的石头取走之后,才能取出下面的石头。栈就可以理解为这样一个模型,栈顶就是瓶子口,栈底就是瓶子底。
下面我们看下栈的相关概念:
栈顶: 允许进行插入和删除的一端
栈底: 不允许进行插入和删除的一端
空栈: 不含任何数据元素的栈
进栈: 又称压栈,在栈中添加一个元素
出栈: 又称弹栈,从栈中删除一个元素
二、顺序栈
栈的顺序存储结构,简称为顺序栈,和线性表很类似,是用一维数组来存储栈。
1.定义
#define STACKSIZE 100
typedef int DataType;
typedef struct
{
DataType data[STACKSIZE]; //数组
int top; //栈顶指针
}SeqStack;
2.栈的初始化操作
void initstakk(SeqStack* s)
{
s->top = -1;
}
初始化时,使栈顶指针为-1,每添加一个元素,栈顶指针top加1,假如添加了1、2、3三个元素,top就是从-1变为2。
3.删除栈中所有元素
void clearstack(SeqStack* s) //删除栈中所有元素
{
s->top = -1;
}
删除时,直接使栈顶指针等于-1,前面添加的元素就被删除了。
4.判断栈是否为空
bool stackempty(SeqStack* s)
{
return s->top == -1; //栈定指针等于-1时,栈为空,返回true,非空返回false
}
5.判断栈是否为满
bool stackfull(SeqStack* s)
{
return s->top == STACKSIZE-1; //即判断栈顶指针是否指向数组最大下标
}
6.压栈
typedef int Status;
#define ERROR 1
#define OK 1
Status push(SeqStack* s,DataType e)
{
if(stackfull(s))
{
return ERROR;
}
++s->top; //top由-1改为0
s->data[s->top] = e; //即s->data[0] = e
return OK;
}
7.获取栈顶元素
Status getTop(SeqStack* s,DataType* e)
{
if(stackempty(s))
{
return ERROR;
}
*e= s->data[s->top];
return OK;
}
8.出栈
Status pop(SeqStack* s,DataType* e)
{
if(s->top == -1)
{
return ERROR;
}
*e= s->data[s->top--];
return OK;
}
9.获取栈中存储元素个数
int stackLength(SeqStack* s)
{
return s->top + 1;
}
// An highlighted block
var foo = 'bar';
// An highlighted block
var foo = 'bar';
三、链栈
栈的链式存储结构,简称链栈,可以看作是一个单链表。
1.定义
typedef int DataType;
typedef struct
{
DataType data;
struct stackNode* next;
}StackNode;
typedef struct
{
StackNode* top; //栈顶指针
int size; //栈的元素个数
}Linkstack;
2.初始化操作
void initStack(LinkStack* s)
{
s->top = NULL;
s->count = 0;
}
3.判断栈是否为空
bool stackEmpty(LinkStack* s)
{
//return s->count == 0 ? true:false;
return s->count == 0;
}
4.压栈
Status push(LinkStack* s,DataType e)
{
StackNode* n = (StackNode*)malloc(sizeof(StackNode));
n->data = 0;
n->next = s->top;
s->top = n;
s->count++;
return OK;
}
5.删除栈中所有元素
void clearStack(LinkStack* s)
{
StackNode* p = s->top;
while(p) //判断p是否为空,不为空执行循环
{
StackNode* q = p;
p = p->next;
free(q);
}
s->count = 0;
s->top = NULL;
}
6.获取栈顶元素
DataType* getTop(LinkStack* s)
{
if(stackEmpty(s)) //判断栈是否为空
{
return NULL;
}
return &s->top->data;;
}
注意无论取多少次,获得的元素都是相同的,栈顶指针不会移动。
7.出栈
Status pop(LinkStack* s,DataType* e)
{
if(stackEmpty(s)) //判断栈是否为空
{
return ERROR;
}
*e = s->top->data;
StackNode* p = s->top;
s->top = p->next;
free(p);
s->count--;
return OK;
}
8.获取栈中元素个数
int stackLength(LinkStack* s)
{
return s->count;
}