目录
2.插入元素到栈顶(表尾)的操作称为入栈PUSH;从栈顶(表尾)删除最后一个元素的操作称为出栈POP
一、栈的基本知识
1.栈(stack)是一个特殊的线性表,是将插入和删除操作限定在表尾的线性表。表尾成为栈顶Top,表头成为栈底Base。栈的特点:先进后出;栈也可以是顺序存储结构(顺序栈)或链式存储结构(链式栈)。
2.插入元素到栈顶(表尾)的操作称为入栈PUSH;从栈顶(表尾)删除最后一个元素的操作称为出栈POP。
3.栈的应用案例:进制转换、括号匹配、表达式求值
4.进制转换案例
5.括号匹配案例
先入栈的括号后匹配,后入栈的括号先匹配。
左括号入栈,遇到右括号就和栈顶的括号匹配,如果能匹配上就将栈顶元素出栈。然后继续匹配右括号和栈顶的元素。
6.表达式求值案例
这里运用的是运算符优先算法:
(1) 我们可以将表达式分为三部分:
表达式起始和结束符是假设的
(2) 需要用到两个栈
(3) 遍历表达式的字符
二、顺序栈
可以将顺序栈看为数组
对于顺序栈:栈底的元素从下标0开始
top指针指向栈顶元素 + 1的位置,base指针指向栈底元素
栈中元素个数 = top - base
三、顺序栈的基本操作
1.顺序栈的定义
typedef struct
{
int *top; //栈顶指针
int *base; //栈底指针
int stackSize; //栈的最大元素个数
}SqStack;
2.初始化
void initStack(SqStack &S)
{
S.base = new int[MAXSIZE];
S.top = S.base;
S.stackSize = MAXSIZE;
}
3.判断栈是否为空
bool stackEmpty(SqStack S)
{
if(S.top == S.base)
{
return true;
}
else
{
return false;
}
4.求顺序栈的长度
int stackLength(SqStack S)
{
return S.top - S.base;
}
5.清空顺序栈
并不需要一个一个得清除元素,只需当做一个空栈。
void clearStack(SqStack &S)
{
//如果这个栈存在
if(S.base)
{
S.top = S.base;
}
}
6.销毁顺序栈
void destroyStack(SqStack &S)
{
//如果这个栈存在
if(S.base)
{
delete S.base; //相当于将栈所占用的空间给释放
S.stackSize = 0;
S.top = S.base = NULL;
}
}
7.顺序栈的入栈
void pushStack(SqStack &S, int e)
{
//先判断栈是否已经满了
if(S.top - S.base == S.stackSize)
{
return;
}
else
{
*S.top = e; //top是指针,它指向的就是栈的元素
S.top++;
//也可以写为*S.top++ = e;
}
8.顺序栈的出栈
int popStack(SqStack &S, int e)
{
//先判断栈是否为空
if(S.top == S.base)
{
return;
}
//要先--,因为top是指向栈顶元素的上一个地方
S.top--;
e = *S.top;
//也可以写为e = *--S.top;
return e;
四、链栈
链栈可以看作是单链表,有数据域和指针域
第n个结点的指针域指向的是第n-1个结点,且没有头结点,和单链表有区别
S头指针就是栈顶,头指针为NULL时表示空栈
五、链栈的基本操作
1.链栈的定义
typedef struct stackNode
{
int data;
struct stackNode *next;
}stackNode; //将stackNode定义为struct stackNode类型
typedef struct stackNode *stackLink; //将stackLink定义为struct stackNode*类型
//链栈表示stackLink S,结点表示stackNode *p;
2.链栈的初始化
void initStack(stackLink &S)
{
S = NULL;
}
3.判断是否为空栈
bool isEmpty(stackLink &S)
{
if(S == NULL)
{
return true;
}
else
{
return false;
}
}
4. 链栈的入栈
void pushStack(stackLink &S, int e)
{
stackNode *p = new stackNode;
p->data = e;
p->next = S;
S = p;
}
5.链栈的出栈
返回出栈的元素
int popStack(stackLink &S, int e)
{
e = S->data;
stackNode *p = new stackNode;
p = S;
S = S->next;
delete p;
return e;
}
六、栈与递归
函数的递归调用遵循后调用的先返回(返回就是函数执行完毕返回返回值),类似于栈的后进先出。而每次调用时需要用到的参数或变量都存在系统的栈里。所以递归需要系统提供栈来实现。